Finished fixing input back to prev-sokol feature parity

This commit is contained in:
Edward R. Gonzalez 2024-06-19 18:09:11 -04:00
parent 6f4a5e215c
commit 5d6f996d3c
11 changed files with 155 additions and 94 deletions

View File

@ -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 ]

View File

@ -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
}

View File

@ -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()
}

View File

@ -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")

View File

@ -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 {

View File

@ -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
{

View File

@ -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

View File

@ -399,6 +399,10 @@ next :: proc {
next_queue_iterator,
}
peek_back :: proc {
queue.peek_back,
}
peek_front :: proc {
queue.peek_front,
}

View File

@ -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 {

View File

@ -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

Binary file not shown.