diff --git a/code/sectr/app/event.odin b/code/sectr/app/event.odin new file mode 100644 index 0000000..7ba6dc6 --- /dev/null +++ b/code/sectr/app/event.odin @@ -0,0 +1,3 @@ +package sectr + + diff --git a/code/sectr/app/screen.odin b/code/sectr/app/screen.odin index 3d0c02d..f086773 100644 --- a/code/sectr/app/screen.odin +++ b/code/sectr/app/screen.odin @@ -252,8 +252,8 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b } if input_box.active { - array_append( & value_str, input.keyboard_events.chars_pressed ) - array_clear( input.keyboard_events.chars_pressed ) + array_append( & value_str, input.codes_pressed ) + array_clear( input.codes_pressed ) } else if input_box.was_active { diff --git a/code/sectr/app/state.odin b/code/sectr/app/state.odin index e1451a6..dcfc4d6 100644 --- a/code/sectr/app/state.odin +++ b/code/sectr/app/state.odin @@ -210,6 +210,10 @@ State :: struct { input_prev : ^InputState, input : ^InputState, + // Note(Ed): Do not modify directly, use its interface in app/event.odin + staged_input_events : Array(InputEvent), + // TODO(Ed): Add a multi-threaded guard for accessing or mutating staged_input_events. + debug : DebugData, project : Project, @@ -226,6 +230,7 @@ State :: struct { // using frametime : FrameTime, sleep_is_granular : b32, + frame : u64, frametime_delta_seconds : f64, frametime_delta_ms : f64, frametime_delta_ns : Duration, diff --git a/code/sectr/engine/.render.odin b/code/sectr/engine/.render_sokol_test.odin similarity index 100% rename from code/sectr/engine/.render.odin rename to code/sectr/engine/.render_sokol_test.odin diff --git a/code/sectr/engine/client_api.odin b/code/sectr/engine/client_api.odin index 708a9ab..a3b6a58 100644 --- a/code/sectr/engine/client_api.odin +++ b/code/sectr/engine/client_api.odin @@ -110,19 +110,30 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem for & input in input_data { using input error : AllocatorError - keyboard_events.keys_pressed, error = make( Array(KeyCode), Kilo, persistent_slab_allocator() ) - ensure(error == AllocatorError.None, "Failed to allocate input.keyboard_events.keys_pressed array") - keyboard_events.chars_pressed, error = make( Array(rune), Kilo, persistent_slab_allocator() ) - ensure(error == AllocatorError.None, "Failed to allocate input.keyboard_events.chars_pressed array") + + events, error = make( Array(InputEvent), Kilo, persistent_slab_allocator() ) + ensure(error == AllocatorError.None, "Failed to allocate input.events array") + + key_events, error = make( Array(InputKeyEvent), Kilo, persistent_slab_allocator() ) + ensure(error == AllocatorError.None, "Failed to allocate key_events array") + + mouse_events, error = make( Array(InputMouseEvent), Kilo, persistent_slab_allocator() ) + ensure(error == AllocatorError.None, "Failed to allocate mouse_events array") + + codes_pressed, error = make( Array(rune), Kilo, persistent_slab_allocator() ) + ensure(error == AllocatorError.None, "Failed to allocate codes_pressed array") } + + input_staged_events, error := make( Array(InputEvent), Kilo, persistent_slab_allocator() ) + ensure(error == AllocatorError.None, "Failed to allocate input_staged_events array") } // Configuration Load // TODO(Ed): Make this actually load from an ini { using config - resolution_width = 1000 - resolution_height = 600 + resolution_width = 1600 + resolution_height = 900 refresh_rate = 0 cam_min_zoom = 0.10 @@ -281,19 +292,19 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem // path_squidgy_slimes := strings.concatenate( { Path_Assets, "Squidgy Slimes.ttf" } ) // font_squidgy_slimes = font_load( path_squidgy_slimes, 24.0, "Squidgy_Slime" ) - // path_firacode := strings.concatenate( { Path_Assets, "FiraCode-Regular.ttf" } ) - // font_firacode = font_load( path_firacode, 24.0, "FiraCode" ) + path_firacode := strings.concatenate( { Path_Assets, "FiraCode-Regular.ttf" } ) + font_firacode = font_load( path_firacode, 24.0, "FiraCode" ) // path_open_sans := strings.concatenate( { Path_Assets, "OpenSans-Regular.ttf" } ) // font_open_sans = font_load( path_open_sans, 24.0, "OpenSans" ) - path_noto_sans := strings.concatenate( { Path_Assets, "NotoSans-Regular.ttf" } ) - font_noto_sans = font_load( path_noto_sans, 24.0, "NotoSans" ) + // path_noto_sans := strings.concatenate( { Path_Assets, "NotoSans-Regular.ttf" } ) + // font_noto_sans = font_load( path_noto_sans, 24.0, "NotoSans" ) - path_arial_unicode_ms := strings.concatenate( { Path_Assets, "Arial Unicode MS.ttf" } ) - font_arial_unicode_ms = font_load( path_arial_unicode_ms, 24.0, "Arial_Unicode_MS" ) + // path_arial_unicode_ms := strings.concatenate( { Path_Assets, "Arial Unicode MS.ttf" } ) + // font_arial_unicode_ms = font_load( path_arial_unicode_ms, 24.0, "Arial_Unicode_MS" ) - default_font = font_arial_unicode_ms + default_font = font_firacode log( "Default font loaded" ) } @@ -391,18 +402,19 @@ reload :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem, set_profiler_module_context( prof ) context.logger = to_odin_logger( & Memory_App.logger ) - using Memory_App; - - persistent = persistent_mem - frame = frame_mem - transient = transient_mem - files_buffer = files_buffer_mem + { + using Memory_App; + persistent = persistent_mem + frame = frame_mem + transient = transient_mem + files_buffer = files_buffer_mem + } context.allocator = transient_allocator() context.temp_allocator = transient_allocator() Memory_App.state = get_state() - using state + using Memory_App.state sokol_context = context @@ -503,7 +515,7 @@ tick_work_frame :: #force_inline proc( host_delta_time_ms : f64 ) -> b32 debug.draw_UI_padding_bounds = false debug.draw_ui_content_bounds = false - config.engine_refresh_hz = 165 + // config.engine_refresh_hz = 165 // config.color_theme = App_Thm_Light // config.color_theme = App_Thm_Dusk @@ -535,8 +547,9 @@ tick_frametime :: #force_inline proc( client_tick : ^time.Tick, host_delta_time_ context.temp_allocator = transient_allocator() // profile("Client tick timing processing") - // config.engine_refresh_hz = uint(monitor_refresh_hz) - // config.engine_refresh_hz = 6 + + config.engine_refresh_hz = uint(monitor_refresh_hz) + // config.engine_refresh_hz = 10 frametime_target_ms = 1.0 / f64(config.engine_refresh_hz) * S_To_MS sub_ms_granularity_required := frametime_target_ms <= Frametime_High_Perf_Threshold_MS @@ -578,6 +591,8 @@ tick_frametime :: #force_inline proc( client_tick : ^time.Tick, host_delta_time_ if frametime_elapsed_ms > 60.0 { log( str_fmt("Big tick! %v ms", frametime_elapsed_ms), LogLevel.Warning ) } + + frame += 1 } @export diff --git a/code/sectr/engine/client_api_sokol_callbacks.odin b/code/sectr/engine/client_api_sokol_callbacks.odin index 3cb0d3d..ae8cfe9 100644 --- a/code/sectr/engine/client_api_sokol_callbacks.odin +++ b/code/sectr/engine/client_api_sokol_callbacks.odin @@ -93,14 +93,99 @@ sokol_app_log_callback :: proc "c" ( logf( "%-80s %s::%v", cloned_msg, cloned_tag, line_nr, level = odin_level ) } -sokol_app_event_callback :: proc "c" (event : ^sokol_app.Event) +// TODO(Ed): This needs to queue to a job stask for a event callback handling thread to deal with. +sokol_app_event_callback :: proc "c" (sokol_event : ^sokol_app.Event) { state := get_state(); using state context = sokol_context - if event.type == sokol_app.Event_Type.DISPLAY_CHANGED { - logf("sokol_app - event: Display changed") - logf("refresh rate: %v", sokol_app.refresh_rate()); - monitor_refresh_hz := sokol_app.refresh_rate() + + event : InputEvent + using event + + _sokol_frame_id = sokol_event.frame_count + frame_id = frame + + mouse.pos = { sokol_event.mouse_x, sokol_event.mouse_y } + mouse.delta = { sokol_event.mouse_dx, sokol_event.mouse_dy } + + switch sokol_event.type + { + case .INVALID: + logf("sokol_app - event: INVALID?") + logf("%v", sokol_event) + + case .KEY_DOWN: + type = .Key_Pressed + key = to_key_from_sokol( sokol_event.key_code ) + modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers ) + + case .KEY_UP: + type = .Key_Released + key = to_key_from_sokol( sokol_event.key_code ) + modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers ) + + case .CHAR: + type = .Unicode + codepoint = transmute(rune) sokol_event.char_code + modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers ) + + case .MOUSE_DOWN: + type = .Mouse_Pressed + mouse.btn = to_mouse_btn_from_sokol( sokol_event.mouse_button ) + modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers ) + + case .MOUSE_UP: + type = .Mouse_Released + mouse.btn = to_mouse_btn_from_sokol( sokol_event.mouse_button ) + modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers ) + + case .MOUSE_SCROLL: + type = .Mouse_Scroll + mouse.scroll = { sokol_event.scroll_x, sokol_event.scroll_y } + modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers ) + + case .MOUSE_MOVE: + type = .Mouse_Move + modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers ) + + case .MOUSE_ENTER: + type = .Mouse_Enter + modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers ) + + case .MOUSE_LEAVE: + type = .Mouse_Leave + modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers ) + + // TODO(Ed): Add support + case .TOUCHES_BEGAN: + case .TOUCHES_MOVED: + case .TOUCHES_ENDED: + case .TOUCHES_CANCELLED: + + case .RESIZED: + + case .ICONIFIED: + + case .RESTORED: + + case .FOCUSED: + + case .UNFOCUSED: + + case .SUSPENDED: + + case .RESUMED: + + case .QUIT_REQUESTED: + + case .CLIPBOARD_PASTED: + + case .FILES_DROPPED: + + case .DISPLAY_CHANGED: + logf("sokol_app - event: Display changed") + logf("refresh rate: %v", sokol_app.refresh_rate()) + monitor_refresh_hz := sokol_app.refresh_rate() } } diff --git a/code/sectr/engine/render_vefc.odin b/code/sectr/engine/render_testing_text.odin similarity index 96% rename from code/sectr/engine/render_vefc.odin rename to code/sectr/engine/render_testing_text.odin index d11604d..35892c1 100644 --- a/code/sectr/engine/render_vefc.odin +++ b/code/sectr/engine/render_testing_text.odin @@ -1,6 +1,7 @@ package sectr import ve "codebase:font/VEFontCache" +import sokol_app "thirdparty:sokol/app" import sokol_gfx "thirdparty:sokol/gfx" import sokol_glue "thirdparty:sokol/glue" import "core:time" @@ -80,8 +81,7 @@ render :: proc() // "Draw text" using immediate mode api { @static index : i32 - index += 1 - text_test_str := str_fmt("frametime: %0.2f\nframe id : %d", frametime_avg_ms, index ) + text_test_str := str_fmt("frametime : %0.6f\nframe id : %d\nsokol_frame: %d", frametime_avg_ms, frame, sokol_app.frame_count() ) // log(text_test_str) // text_test_str := str_fmt("HELLO VE FONT CACHE!") // text_test_str := str_fmt("C") @@ -95,7 +95,7 @@ render :: proc() ve.set_colour( & ve_font_cache, { 1.0, 1.0, 1.0, 1.0 } ) ve.configure_snap( & ve_font_cache, u32(state.app_window.extent.x * 2.0), u32(state.app_window.extent.y * 2.0) ) - ve.draw_text( & ve_font_cache, fdef.ve_id, text_test_str, {0.1, 0.2}, Vec2{1 / width, 1 / height} ) + ve.draw_text( & ve_font_cache, fdef.ve_id, text_test_str, {0.0, 0.975}, Vec2{1 / width, 1 / height} ) } diff --git a/code/sectr/engine/update.odin b/code/sectr/engine/update.odin index dd82196..df3c5d6 100644 --- a/code/sectr/engine/update.odin +++ b/code/sectr/engine/update.odin @@ -79,7 +79,7 @@ update :: proc( delta_time : f64 ) -> b32 } state.input, state.input_prev = swap( state.input, state.input_prev ) - // poll_input( state.input_prev, state.input ) + pull_staged_input_events( state.input, & state.staged_input_events ) debug_actions : DebugActions = {} // poll_debug_actions( & debug_actions, state.input ) diff --git a/code/sectr/font/provider_VEFontCache.odin b/code/sectr/font/provider_VEFontCache.odin index 6c39059..90fe472 100644 --- a/code/sectr/font/provider_VEFontCache.odin +++ b/code/sectr/font/provider_VEFontCache.odin @@ -545,7 +545,7 @@ font_load :: proc(path_file : string, def.path_file = path_file // TODO(Ed): Load even sizes from 8px to upper bound. - def.ve_id = ve.load_font( & provider_data.ve_font_cache, desired_id, font_data, 80.0 ) + def.ve_id = ve.load_font( & provider_data.ve_font_cache, desired_id, font_data, 18.0 ) fid := FontID { key, desired_id } return fid diff --git a/code/sectr/grime/mappings.odin b/code/sectr/grime/mappings.odin index e3d8a24..df61292 100644 --- a/code/sectr/grime/mappings.odin +++ b/code/sectr/grime/mappings.odin @@ -297,6 +297,12 @@ add :: proc { add_range2, } +append :: proc { + grime.array_append_array, + grime.array_append_slice, + grime.array_append_value, +} + bivec3 :: proc { bivec3_via_f32s, vec3_to_bivec3, diff --git a/code/sectr/input/input_raylib.odin b/code/sectr/input/.input_raylib.odin similarity index 100% rename from code/sectr/input/input_raylib.odin rename to code/sectr/input/.input_raylib.odin diff --git a/code/sectr/input/actions.odin b/code/sectr/input/actions.odin index 3876406..379e536 100644 --- a/code/sectr/input/actions.odin +++ b/code/sectr/input/actions.odin @@ -1 +1,12 @@ -package sectr \ No newline at end of file +package sectr + + +InputBindCallback :: #type proc(user_ptr : rawptr) + +InputBind :: struct +{ + + + user_ptr : rawptr, + callback : InputBindCallback, +} diff --git a/code/sectr/input/event.odin b/code/sectr/input/event.odin index 2432dbc..b0b2c18 100644 --- a/code/sectr/input/event.odin +++ b/code/sectr/input/event.odin @@ -1 +1,63 @@ package sectr + +InputEventType :: enum u32 { + Key_Pressed, + Key_Released, + Mouse_Pressed, + Mouse_Released, + Mouse_Scroll, + Mouse_Move, + Mouse_Enter, + Mouse_Leave, + Unicode, +} + +InputEvent :: struct +{ + frame_id : u64, + type : InputEventType, + key : KeyCode, + modifiers : ModifierCodeFlags, + mouse : struct { + btn : MouseBtn, + pos : Vec2, + delta : Vec2, + scroll : Vec2, + }, + codepoint : rune, + + // num_touches : u32, + // touches : Touchpoint, + + _sokol_frame_id : u64, +} + +InputKeyEvent :: struct { + frame_id : u64, + type : InputEventType, + key : KeyCode, + modifiers : ModifierCodeFlags, +} + +InputMouseEvent :: struct { + frame_id : u64, + type : InputEventType, + key : KeyCode, + modifiers : ModifierCodeFlags, +} + +// Note(Ed): There is a staged_input_events : Array(InputEvent), in the state.odin's State struct + +append_staged_input_events :: #force_inline proc() { + // TODO(Ed) : Add guards for multi-threading + + state := get_state() + array_append( & state.staged_input_events, event ) +} + +pull_staged_input_events :: proc( input : ^InputState, staged_events : ^Array(InputEvent) ) +{ + // TODO(Ed) : Add guards for multi-threading + + +} diff --git a/code/sectr/input/input.odin b/code/sectr/input/input.odin index 84b547f..27d9d65 100644 --- a/code/sectr/input/input.odin +++ b/code/sectr/input/input.odin @@ -31,6 +31,8 @@ MouseBtn :: enum u32 { Back = 0x5, Extra = 0x6, + Invalid = 0x100, + count } @@ -40,7 +42,11 @@ KeyboardState :: struct #raw_union { ignored : DigitalBtn, - __0x02_0x07_Unassigned__ : [ 6 * size_of( DigitalBtn)] u8, + // GFLW / Sokol + menu, + world_1, world_2 : DigitalBtn, + + __0x05_0x07_Unassigned__ : [ 3 * size_of( DigitalBtn)] u8, tab, backspace : DigitalBtn, @@ -61,8 +67,7 @@ KeyboardState :: struct #raw_union { right_shift, right_control : DigitalBtn, - __0x19_Unassigned__ : [ 1 * size_of( DigitalBtn )] u8, - + print_screen, pause, escape, home, @@ -136,9 +141,27 @@ KeyboardState :: struct #raw_union { F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12 : DigitalBtn, insert, delete : DigitalBtn, + + F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25 : DigitalBtn, } } +ModifierCode :: enum u32 { + Shift, + Control, + Alt, + Left_Mouse, + Right_Mouse, + Middle_Mouse, + Left_Shift, + Right_Shift, + Left_Control, + Right_Control, + Left_Alt, + Right_Alt, +} +ModifierCodeFlags :: bit_set[ModifierCode; u32] + MouseState :: struct { using _ : struct #raw_union { btns : [16] DigitalBtn, @@ -161,11 +184,9 @@ InputState :: struct { keyboard : KeyboardState, mouse : MouseState, - keyboard_events : KeyboardEvents, -} + events : Array(InputEvent), + key_events : Array(InputKeyEvent), + mouse_events : Array(InputMouseEvent), -// TODO(Ed): Whats the lifetime of these events? (So far we're picking per full-frame) -KeyboardEvents :: struct { - keys_pressed : Array(KeyCode), - chars_pressed : Array(rune), + codes_pressed : Array(rune), } diff --git a/code/sectr/input/input_sokol.odin b/code/sectr/input/input_sokol.odin index 3876406..602af13 100644 --- a/code/sectr/input/input_sokol.odin +++ b/code/sectr/input/input_sokol.odin @@ -1 +1,109 @@ -package sectr \ No newline at end of file +package sectr + +import "base:runtime" +import "core:os" +import "core:c/libc" +import sokol_app "thirdparty:sokol/app" + +to_modifiers_code_from_sokol :: proc( sokol_modifiers : u32 ) -> ( modifiers : ModifierCodeFlags ) +{ + if sokol_modifiers & sokol_app.MODIFIER_SHIFT != 0 { + modifiers |= { .Shift } + } + if sokol_modifiers & sokol_app.MODIFIER_CTRL != 0 { + modifiers |= { .Control } + } + if sokol_modifiers & sokol_app.MODIFIER_ALT != 0 { + modifiers |= { .Alt } + } + if sokol_modifiers & sokol_app.MODIFIER_LMB != 0 { + modifiers |= { .Left_Mouse } + } + if sokol_modifiers & sokol_app.MODIFIER_RMB != 0 { + modifiers |= { .Right_Mouse } + } + if sokol_modifiers & sokol_app.MODIFIER_MMB != 0 { + modifiers |= { .Middle_Mouse } + } + if sokol_modifiers & sokol_app.MODIFIER_LSHIFT != 0 { + modifiers |= { .Left_Shift } + } + if sokol_modifiers & sokol_app.MODIFIER_RSHIFT != 0 { + modifiers |= { .Right_Shift } + } + if sokol_modifiers & sokol_app.MODIFIER_LCTRL != 0 { + modifiers |= { .Left_Control } + } + if sokol_modifiers & sokol_app.MODIFIER_RCTRL != 0 { + modifiers |= { .Right_Control } + } + if sokol_modifiers & sokol_app.MODIFIER_LALT != 0 { + modifiers |= { .Left_Alt } + } + if sokol_modifiers & sokol_app.MODIFIER_RALT != 0 { + modifiers |= { .Right_Alt } + } + + return +} + +to_key_from_sokol :: proc( sokol_key : sokol_app.Keycode ) -> ( key : KeyCode ) +{ + world_code_offset :: i32(sokol_app.Keycode.WORLD_1) - i32(KeyCode.world_1) + arrow_code_offset :: i32(sokol_app.Keycode.RIGHT) - i32(KeyCode.right) + func_row_code_offset :: i32(sokol_app.Keycode.F1) - i32(KeyCode.F1) + func_extra_code_offset :: i32(sokol_app.Keycode.F13) - i32(KeyCode.F25) + keypad_num_offset :: i32(sokol_app.Keycode.KP_0) - i32(KeyCode.kpad_0) + + switch sokol_key { + case .INVALID ..= .GRAVE_ACCENT : key = transmute(KeyCode) sokol_key + case .WORLD_1, .WORLD_2 : key = transmute(KeyCode) (i32(sokol_key) - world_code_offset) + case .ESCAPE : key = .escape + case .ENTER : key = .enter + case .TAB : key = .tab + case .BACKSPACE : key = .backspace + case .INSERT : key = .insert + case .DELETE : key = .delete + case .RIGHT ..= .UP : key = transmute(KeyCode) (i32(sokol_key) - arrow_code_offset) + case .PAGE_UP : key = .page_up + case .PAGE_DOWN : key = .page_down + case .HOME : key = .home + case .END : key = .end + case .CAPS_LOCK : key = .caps_lock + case .SCROLL_LOCK : key = .scroll_lock + case .NUM_LOCK : key = .num_lock + case .PRINT_SCREEN : key = .print_screen + case .PAUSE : key = .pause + case .F1 ..= .F12 : key = transmute(KeyCode) (i32(sokol_key) - func_row_code_offset) + case .F13 ..= .F25 : key = transmute(KeyCode) (i32(sokol_key) - func_extra_code_offset) + case .KP_0 ..= .KP_9 : key = transmute(KeyCode) (i32(sokol_key) - keypad_num_offset) + case .KP_DECIMAL : key = .kpad_decimal + case .KP_DIVIDE : key = .kpad_divide + case .KP_MULTIPLY : key = .kpad_multiply + case .KP_SUBTRACT : key = .kpad_minus + case .KP_ADD : key = .kpad_plus + case .KP_ENTER : key = .kpad_enter + case .KP_EQUAL : key = .kpad_equals + case .LEFT_SHIFT : key = .left_shift + case .LEFT_CONTROL : key = .left_control + case .LEFT_ALT : key = .left_alt + case .LEFT_SUPER : key = .ignored + case .RIGHT_SHIFT : key = .right_shift + case .RIGHT_CONTROL : key = .right_control + case .RIGHT_ALT : key = .right_alt + case .RIGHT_SUPER : key = .ignored + case .MENU : key = .menu + } + return +} + +to_mouse_btn_from_sokol :: proc( sokol_mouse : sokol_app.Mousebutton ) -> ( btn : MouseBtn ) +{ + switch sokol_mouse { + case .LEFT : btn = .Left + case .MIDDLE : btn = .Middle + case .RIGHT : btn = .Right + case .INVALID : btn = .Invalid + } + return +} diff --git a/code/sectr/input/keycode.odin b/code/sectr/input/keycode.odin index 1d95be9..c0708c7 100644 --- a/code/sectr/input/keycode.odin +++ b/code/sectr/input/keycode.odin @@ -6,9 +6,10 @@ KeyCode :: enum u32 { null = 0x00, ignored = 0x01, - // 0x02 - // 0x03 - // 0x04 + menu = 0x02, + world_1 = 0x03, + world_2 = 0x04, + // 0x05 // 0x06 // 0x07 @@ -36,8 +37,7 @@ KeyCode :: enum u32 { right_shift = 0x17, right_control = 0x18, - // 0x19 - + print_screen = 0x19, pause = 0x1A, escape = '\x1B', // 0x1B home = 0x1C, @@ -150,5 +150,19 @@ KeyCode :: enum u32 { insert = 0x7E, delete = 0x7F, - count = 0x80, + F13 = 0x80, + F14 = 0x81, + F15 = 0x82, + F16 = 0x83, + F17 = 0x84, + F18 = 0x85, + F19 = 0x86, + F20 = 0x87, + F21 = 0x88, + F22 = 0x89, + F23 = 0x8A, + F24 = 0x8B, + F25 = 0x8C, + + count = 0x8D, }