Finished fixing input back to prev-sokol feature parity
This commit is contained in:
parent
6f4a5e215c
commit
5d6f996d3c
@ -19,24 +19,29 @@ make_queue :: proc( $QueueType : typeid/Queue($Type), capacity := queue.DEFAULT_
|
||||
|
||||
push_back_slice_queue :: proc( self : ^$QueueType / Queue($Type), slice : []Type ) -> ( error : AllocatorError )
|
||||
{
|
||||
num := cast(uint) len(slice)
|
||||
|
||||
if uint( space_left( self^ )) < num {
|
||||
error = queue._grow( self, self.len + num )
|
||||
if error != .None do return
|
||||
}
|
||||
|
||||
size := uint(len(self.data))
|
||||
insert_from := (self.offset + self.len) % size
|
||||
insert_to := num
|
||||
|
||||
if insert_from + insert_to > size {
|
||||
insert_to = size - insert_from
|
||||
}
|
||||
|
||||
copy( self.data[ insert_from : ], slice[ : insert_to ])
|
||||
copy( self.data[ : insert_from ], slice[ insert_to : ])
|
||||
queue.push_back_elems( self, ..slice )
|
||||
return
|
||||
|
||||
// num := cast(uint) len(slice)
|
||||
|
||||
// if uint( space_left( self^ )) < num {
|
||||
// error = queue._grow( self, self.len + num )
|
||||
// if error != .None do return
|
||||
// }
|
||||
|
||||
// size := uint(len(self.data))
|
||||
// insert_from := (self.offset + self.len) % size
|
||||
// insert_to := num
|
||||
|
||||
// if insert_from + insert_to > size {
|
||||
// insert_to = size - insert_from
|
||||
// }
|
||||
|
||||
// copy( self.data[ insert_from : ], slice[ : insert_to ])
|
||||
// copy( self.data[ : insert_from ], slice[ insert_to : ])
|
||||
|
||||
// self.len += num
|
||||
// return
|
||||
}
|
||||
|
||||
QueueIterator :: struct( $Type : typeid ) {
|
||||
@ -60,8 +65,10 @@ iterator_queue :: proc( queue : $QueueType / Queue($Type) ) -> QueueIterator(Typ
|
||||
next_queue_iterator :: proc( iter : ^QueueIterator($Type) ) -> ^Type
|
||||
{
|
||||
using iter
|
||||
front_id := (length + offset ) % len(data)
|
||||
elem_id := (length + offset - index) % len(data)
|
||||
data_size := cast(uint) len(data)
|
||||
|
||||
front_id := (length + offset ) % data_size
|
||||
elem_id := (length + offset - index -1 ) % data_size
|
||||
if elem_id == front_id do return nil
|
||||
|
||||
elem := & data[ elem_id ]
|
||||
|
@ -4,11 +4,13 @@ RGBA8 :: struct { r, g, b, a : u8 }
|
||||
RGBAN :: [4]f32
|
||||
|
||||
normalize_rgba8 :: #force_inline proc( color : RGBA8 ) -> RGBAN {
|
||||
quotient : f32 = 1.0 / 255
|
||||
|
||||
result := RGBAN {
|
||||
1.0 / f32(color.r),
|
||||
1.0 / f32(color.g),
|
||||
1.0 / f32(color.b),
|
||||
1.0 / f32(color.a),
|
||||
f32(color.r) * quotient,
|
||||
f32(color.g) * quotient,
|
||||
f32(color.b) * quotient,
|
||||
f32(color.a) * quotient,
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -112,13 +112,13 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
using input_events
|
||||
|
||||
error : AllocatorError
|
||||
events, error = make( Queue(InputEvent), 4 * Kilo, persistent_slab_allocator() )
|
||||
events, error = make( Queue(InputEvent), 4 * Kilo, persistent_allocator(), fixed_cap = true )
|
||||
ensure(error == AllocatorError.None, "Failed to allocate input.events array")
|
||||
|
||||
key_events, error = make( Queue(InputKeyEvent), Kilo, persistent_slab_allocator() )
|
||||
key_events, error = make( Queue(InputKeyEvent), Kilo, persistent_allocator(), fixed_cap = true )
|
||||
ensure(error == AllocatorError.None, "Failed to allocate key_events array")
|
||||
|
||||
mouse_events, error = make( Queue(InputMouseEvent), 2 * Kilo, persistent_slab_allocator() )
|
||||
mouse_events, error = make( Queue(InputMouseEvent), 2 * Kilo, persistent_allocator(), fixed_cap = true )
|
||||
ensure(error == AllocatorError.None, "Failed to allocate mouse_events array")
|
||||
|
||||
codes_pressed, error = make( Array(rune), Kilo, persistent_slab_allocator() )
|
||||
@ -132,8 +132,8 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
// TODO(Ed): Make this actually load from an ini
|
||||
{
|
||||
using config
|
||||
resolution_width = 1600
|
||||
resolution_height = 900
|
||||
resolution_width = 1000
|
||||
resolution_height = 600
|
||||
refresh_rate = 0
|
||||
|
||||
cam_min_zoom = 0.10
|
||||
@ -418,10 +418,10 @@ hot_reload :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_
|
||||
// input_reload()
|
||||
{
|
||||
using input_events
|
||||
reload( & events, persistent_slab_allocator())
|
||||
reload( & key_events, persistent_slab_allocator())
|
||||
reload( & mouse_events, persistent_slab_allocator())
|
||||
codes_pressed.backing = persistent_slab_allocator()
|
||||
reload( & events, runtime.nil_allocator())
|
||||
reload( & key_events, runtime.nil_allocator())
|
||||
reload( & mouse_events, runtime.nil_allocator())
|
||||
codes_pressed.backing = persistent_slab_allocator()
|
||||
staged_input_events.backing = persistent_slab_allocator()
|
||||
}
|
||||
|
||||
|
@ -119,55 +119,74 @@ sokol_app_event_callback :: proc "c" (sokol_event : ^sokol_app.Event)
|
||||
logf("%v", sokol_event)
|
||||
|
||||
case .KEY_DOWN:
|
||||
if sokol_event.key_repeat do return
|
||||
|
||||
type = .Key_Pressed
|
||||
key = to_key_from_sokol( sokol_event.key_code )
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
// logf("Key pressed(sokol): %v", key)
|
||||
// logf("frame (sokol): %v", frame_id )
|
||||
|
||||
case .KEY_UP:
|
||||
if sokol_event.key_repeat do return
|
||||
|
||||
type = .Key_Released
|
||||
key = to_key_from_sokol( sokol_event.key_code )
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
// logf("Key released(sokol): %v", key)
|
||||
// logf("frame (sokol): %v", frame_id )
|
||||
|
||||
case .CHAR:
|
||||
if sokol_event.key_repeat do return
|
||||
|
||||
type = .Unicode
|
||||
codepoint = transmute(rune) sokol_event.char_code
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
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 )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
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 )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
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 )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
case .MOUSE_MOVE:
|
||||
type = .Mouse_Move
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
case .MOUSE_ENTER:
|
||||
type = .Mouse_Enter
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
case .MOUSE_LEAVE:
|
||||
type = .Mouse_Leave
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
// TODO(Ed): Add support
|
||||
case .TOUCHES_BEGAN:
|
||||
@ -211,8 +230,6 @@ sokol_app_event_callback :: proc "c" (sokol_event : ^sokol_app.Event)
|
||||
monitor_refresh_hz := sokol_app.refresh_rate()
|
||||
sokol_app.consume_event()
|
||||
}
|
||||
|
||||
append_staged_input_events( event )
|
||||
}
|
||||
|
||||
#endregion("Sokol App")
|
||||
|
@ -113,7 +113,7 @@ render_mode_screenspace :: proc()
|
||||
screen_corners := screen_get_corners()
|
||||
|
||||
position := screen_corners.top_right
|
||||
position.x -= app_window.extent.x
|
||||
position.x -= app_window.extent.x * 0.5
|
||||
position.y -= debug.draw_debug_text_y
|
||||
|
||||
content := str_fmt_buffer( draw_text_scratch[:], format, ..args )
|
||||
@ -122,37 +122,36 @@ render_mode_screenspace :: proc()
|
||||
debug.draw_debug_text_y += 14
|
||||
}
|
||||
|
||||
// "Draw text" using immediate mode api
|
||||
{
|
||||
font_provider := & state.font_provider_data
|
||||
using font_provider
|
||||
|
||||
@static index : i32
|
||||
text_test_str := str_fmt("frametime : %0.6f\nframetime(sokol): %0.2f\nframe id : %d\nsokol_frame: %d", frametime_delta_ms, sokol_app.frame_delta() * S_To_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")
|
||||
|
||||
// font_provider := & state.font_provider_data
|
||||
// fdef := hmap_chained_get( font_cache, default_font.key )
|
||||
|
||||
width := app_window.extent.x * 2
|
||||
height := app_window.extent.y * 2
|
||||
|
||||
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, font_provider_resolve_draw_id(default_font), text_test_str, {0.0, 0.975}, Vec2{1 / width, 1 / height} )
|
||||
}
|
||||
|
||||
debug.debug_text_vis = true
|
||||
if debug.debug_text_vis
|
||||
{
|
||||
fps_msg := str_fmt( "FPS: %f", fps_avg)
|
||||
fps_msg_width := cast(f32) u32(measure_text_size( fps_msg, default_font, 12.0, 0.0 ).x) + 0.5
|
||||
fps_msg := str_fmt( "FPS: %0.2f", fps_avg)
|
||||
fps_msg_width := measure_text_size( fps_msg, default_font, 12.0, 0.0 ).x
|
||||
fps_msg_pos := screen_get_corners().top_right - { fps_msg_width, 0 } - { 5, 5 }
|
||||
debug_draw_text( fps_msg, fps_msg_pos, 12.0, color = Color_White )
|
||||
// debug_draw_text( fps_msg, {}, 12.0, color = Color_White )
|
||||
debug_draw_text( fps_msg, fps_msg_pos, 38.0, color = Color_Red )
|
||||
|
||||
// debug_text( "Screen Width : %v", rl.GetScreenWidth () )
|
||||
// debug_text( "Screen Height: %v", rl.GetScreenHeight() )
|
||||
// debug_text( "frametime_target_ms : %f ms", frametime_target_ms )
|
||||
debug_text( "frametime : %f ms", frametime_delta_ms )
|
||||
// debug_text( "frametime_last_elapsed_ms : %f ms", frametime_elapsed_ms )
|
||||
if replay.mode == ReplayMode.Record {
|
||||
debug_text( "Recording Input")
|
||||
}
|
||||
if replay.mode == ReplayMode.Playback {
|
||||
debug_text( "Replaying Input")
|
||||
}
|
||||
// debug_text("Zoom Target: %v", project.workspace.zoom_target)
|
||||
|
||||
if debug.mouse_vis {
|
||||
debug_text("Mouse scroll: %v", input.mouse.scroll )
|
||||
debug_text("Mouse Delta : %v", input.mouse.delta )
|
||||
debug_text("Mouse Position (Render) : %v", input.mouse.raw_pos )
|
||||
debug_text("Mouse Position (Screen) : %v", input.mouse.pos )
|
||||
debug_text("Mouse Position (Workspace View): %v", screen_to_ws_view_pos(input.mouse.pos) )
|
||||
// rl.DrawCircleV( input.mouse.raw_pos, 10, Color_White_A125 )
|
||||
// rl.DrawCircleV( screen_to_render_pos(input.mouse.pos), 2, Color_BG )
|
||||
}
|
||||
|
||||
render_text_layer()
|
||||
}
|
||||
@ -300,7 +299,7 @@ render_text_layer :: proc()
|
||||
|
||||
fs_target_uniform := Ve_Draw_Text_Fs_Params {
|
||||
down_sample = 0,
|
||||
colour = {1.0, 1.0, 1.0, 1},
|
||||
colour = draw_call.colour,
|
||||
}
|
||||
|
||||
if draw_call.pass == .Target_Uncached {
|
||||
|
@ -78,12 +78,17 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
project.workspace.cam.view = transmute(Vec2) window.extent
|
||||
}
|
||||
|
||||
state.input, state.input_prev = swap( state.input, state.input_prev )
|
||||
// state.input, state.input_prev = swap( state.input, state.input_prev )
|
||||
{
|
||||
temp := state.input_prev
|
||||
state.input_prev = state.input
|
||||
state.input = temp
|
||||
}
|
||||
pull_staged_input_events( state.input, & state.input_events, state.staged_input_events )
|
||||
poll_input_events( state.input, state.input_prev, state.input_events )
|
||||
|
||||
debug_actions : DebugActions = {}
|
||||
// poll_debug_actions( & debug_actions, state.input )
|
||||
poll_debug_actions( & debug_actions, state.input )
|
||||
|
||||
// Saving & Loading
|
||||
{
|
||||
|
@ -552,6 +552,7 @@ font_load :: proc(path_file : string,
|
||||
|
||||
for font_size : i32 = Font_Size_Interval; font_size <= Font_Largest_Px_Size; font_size += Font_Size_Interval
|
||||
{
|
||||
logf("Loading at size %v", font_size)
|
||||
id := (font_size / Font_Size_Interval) + (font_size % Font_Size_Interval)
|
||||
ve_id := & def.size_table[id - 1]
|
||||
ve_id^ = ve.load_font( & provider_data.ve_font_cache, desired_id, font_data, 14.0 )
|
||||
@ -567,12 +568,12 @@ font_provider_resolve_draw_id :: proc( id : FontID, size := Font_Use_Default_Siz
|
||||
{
|
||||
state := get_state(); using state
|
||||
|
||||
even_size := math.round(size * (1.0 / f32(Font_Size_Interval))) * f32(Font_Size_Interval)
|
||||
size := clamp( i32( even_size), 4, Font_Largest_Px_Size )
|
||||
def := hmap_chained_get( font_provider_data.font_cache, id.key )
|
||||
size = size if size != i32(Font_Use_Default_Size) else def.default_size
|
||||
def := hmap_chained_get( font_provider_data.font_cache, id.key )
|
||||
size := size == 0.0 ? f32(def.default_size) : size
|
||||
even_size := math.round(size * (1.0 / f32(Font_Size_Interval))) * f32(Font_Size_Interval)
|
||||
resolved_size := clamp( i32( even_size), 2, Font_Largest_Px_Size )
|
||||
|
||||
id := (size / Font_Size_Interval) + (size % Font_Size_Interval)
|
||||
id := (resolved_size / Font_Size_Interval) + (resolved_size % Font_Size_Interval)
|
||||
ve_id := def.size_table[ id - 1 ]
|
||||
|
||||
width := app_window.extent.x * 2
|
||||
|
@ -399,6 +399,10 @@ next :: proc {
|
||||
next_queue_iterator,
|
||||
}
|
||||
|
||||
peek_back :: proc {
|
||||
queue.peek_back,
|
||||
}
|
||||
|
||||
peek_front :: proc {
|
||||
queue.peek_front,
|
||||
}
|
||||
|
@ -88,6 +88,9 @@ pull_staged_input_events :: proc( input : ^InputState, input_events : ^InputEve
|
||||
key = event.key,
|
||||
modifiers = event.modifiers
|
||||
})
|
||||
// logf("Key pressed(event pushed): %v", event.key)
|
||||
// logf("last key event frame: %v", peek_back(& key_events).frame_id)
|
||||
// logf("last event frame: %v", peek_back(& events).frame_id)
|
||||
|
||||
case .Key_Released:
|
||||
push( & key_events, InputKeyEvent {
|
||||
@ -96,6 +99,9 @@ pull_staged_input_events :: proc( input : ^InputState, input_events : ^InputEve
|
||||
key = event.key,
|
||||
modifiers = event.modifiers
|
||||
})
|
||||
// logf("Key released(event rpushed): %v", event.key)
|
||||
// logf("last key event frame: %v", peek_back(& key_events).frame_id)
|
||||
// logf("last event frame: %v", peek_back(& events).frame_id)
|
||||
|
||||
case .Unicode:
|
||||
append( & codes_pressed, event.codepoint )
|
||||
@ -175,22 +181,39 @@ poll_input_events :: proc( input, prev_input : ^InputState, input_events : Input
|
||||
input.keyboard = {}
|
||||
input.mouse = {}
|
||||
|
||||
// logf("m's value is: %v (prev)", prev_input.keyboard.keys[KeyCode.M] )
|
||||
|
||||
for prev_key, id in prev_input.keyboard.keys {
|
||||
input.keyboard.keys[id].ended_down = prev_key.ended_down
|
||||
}
|
||||
|
||||
for prev_btn, id in prev_input.mouse.btns {
|
||||
input.mouse.btns[id].ended_down = prev_btn.ended_down
|
||||
}
|
||||
|
||||
input_events := input_events
|
||||
using input_events
|
||||
|
||||
@static prev_frame : u64 = u64_max
|
||||
@static prev_frame : u64 = 0
|
||||
|
||||
last_frame := peek_front( & events).frame_id
|
||||
last_frame : u64 = 0
|
||||
if events.len > 0 {
|
||||
last_frame = peek_back( & events).frame_id
|
||||
}
|
||||
|
||||
// No new events, don't update
|
||||
if prev_frame != 0 && last_frame == prev_frame do return
|
||||
if last_frame == prev_frame do return
|
||||
|
||||
Iterate_Key_Events:
|
||||
{
|
||||
iter_obj := iterator( key_events ); iter := & iter_obj
|
||||
for event := next( iter ); event != nil; event = next( iter )
|
||||
{
|
||||
if last_frame == event.frame_id do return
|
||||
if last_frame > event.frame_id {
|
||||
break
|
||||
}
|
||||
// logf("last_frame (iter): %v", last_frame)
|
||||
// logf("frame (iter): %v", event.frame_id )
|
||||
|
||||
key := & input.keyboard.keys[event.key]
|
||||
prev_key := prev_input.keyboard.keys[event.key]
|
||||
@ -206,9 +229,6 @@ poll_input_events :: proc( input, prev_input : ^InputState, input_events : Input
|
||||
key.half_transitions += 1
|
||||
key.ended_down = false
|
||||
}
|
||||
|
||||
frame_transition := first_transition && prev_key.ended_down != key.ended_down ? i32(1) : i32(0)
|
||||
key.half_transitions += frame_transition
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,7 +237,9 @@ poll_input_events :: proc( input, prev_input : ^InputState, input_events : Input
|
||||
iter_obj := iterator( mouse_events ); iter := & iter_obj
|
||||
for event := next( iter ); event != nil; event = next( iter )
|
||||
{
|
||||
if last_frame == event.frame_id do return
|
||||
if last_frame > event.frame_id {
|
||||
break
|
||||
}
|
||||
|
||||
process_digital_btn :: proc( btn : ^DigitalBtn, prev_btn : DigitalBtn, ended_down : b32 )
|
||||
{
|
||||
@ -225,9 +247,6 @@ poll_input_events :: proc( input, prev_input : ^InputState, input_events : Input
|
||||
|
||||
btn.half_transitions += 1
|
||||
btn.ended_down = ended_down
|
||||
|
||||
frame_transition := first_transition && prev_btn.ended_down != btn.ended_down ? i32(1) : i32(0)
|
||||
btn.half_transitions += frame_transition
|
||||
}
|
||||
|
||||
#partial switch event.type {
|
||||
|
@ -39,26 +39,30 @@ MouseBtn :: enum u32 {
|
||||
KeyboardState :: struct #raw_union {
|
||||
keys : [KeyCode.count] DigitalBtn,
|
||||
using individual : struct {
|
||||
|
||||
ignored : DigitalBtn,
|
||||
null : DigitalBtn, // 0x00
|
||||
ignored : DigitalBtn, // 0x01
|
||||
|
||||
// GFLW / Sokol
|
||||
menu,
|
||||
world_1, world_2 : DigitalBtn,
|
||||
// 0x02 - 0x04
|
||||
|
||||
__0x05_0x07_Unassigned__ : [ 3 * size_of( DigitalBtn)] u8,
|
||||
|
||||
tab, backspace : DigitalBtn,
|
||||
// 0x08 - 0x09
|
||||
|
||||
right, left, up, down : DigitalBtn,
|
||||
// 0x0A - 0x0D
|
||||
|
||||
enter : DigitalBtn,
|
||||
enter : DigitalBtn, // 0x0E
|
||||
|
||||
__0x0F_Unassigned__ : [ 1 * size_of( DigitalBtn)] u8,
|
||||
|
||||
caps_lock,
|
||||
scroll_lock,
|
||||
num_lock : DigitalBtn,
|
||||
// 0x10 - 0x12
|
||||
|
||||
left_alt,
|
||||
left_shift,
|
||||
@ -66,6 +70,7 @@ KeyboardState :: struct #raw_union {
|
||||
right_alt,
|
||||
right_shift,
|
||||
right_control : DigitalBtn,
|
||||
// 0x13 - 0x18
|
||||
|
||||
print_screen,
|
||||
pause,
|
||||
@ -75,6 +80,7 @@ KeyboardState :: struct #raw_union {
|
||||
page_up,
|
||||
page_down,
|
||||
space : DigitalBtn,
|
||||
// 0x19 - 0x20
|
||||
|
||||
exlamation,
|
||||
quote_dbl,
|
||||
@ -91,17 +97,18 @@ KeyboardState :: struct #raw_union {
|
||||
minus,
|
||||
period,
|
||||
slash : DigitalBtn,
|
||||
// 0x21 - 0x2F
|
||||
|
||||
nrow_0,
|
||||
nrow_1,
|
||||
nrow_2,
|
||||
nrow_3,
|
||||
nrow_4,
|
||||
nrow_5,
|
||||
nrow_6,
|
||||
nrow_7,
|
||||
nrow_8,
|
||||
nrow_9,
|
||||
nrow_0, // 0x30
|
||||
nrow_1, // 0x31
|
||||
nrow_2, // 0x32
|
||||
nrow_3, // 0x33
|
||||
nrow_4, // 0x34
|
||||
nrow_5, // 0x35
|
||||
nrow_6, // 0x36
|
||||
nrow_7, // 0x37
|
||||
nrow_8, // 0x38
|
||||
nrow_9, // 0x39
|
||||
|
||||
__0x3A_Unassigned__ : [ 1 * size_of(DigitalBtn)] u8,
|
||||
|
||||
|
BIN
docs/input sys design.pur
Normal file
BIN
docs/input sys design.pur
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user