Started to setup input events based off sokol
Will replace the input polling done with raylib. Going to also provide the more robust input tracking for consuming events with the UI interactions
This commit is contained in:
		
							
								
								
									
										3
									
								
								code/sectr/app/event.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								code/sectr/app/event.odin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| package sectr | ||||
|  | ||||
|  | ||||
| @@ -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 | ||||
| 					{ | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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() | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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} ) | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| @@ -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 ) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -1 +1,12 @@ | ||||
| package sectr | ||||
| package sectr | ||||
|  | ||||
|  | ||||
| InputBindCallback :: #type proc(user_ptr : rawptr) | ||||
|  | ||||
| InputBind :: struct | ||||
| { | ||||
|  | ||||
|  | ||||
| 	user_ptr : rawptr, | ||||
| 	callback : InputBindCallback, | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
| 	 | ||||
| } | ||||
|   | ||||
| @@ -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), | ||||
| } | ||||
|   | ||||
| @@ -1 +1,109 @@ | ||||
| package sectr | ||||
| 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 | ||||
| } | ||||
|   | ||||
| @@ -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, | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user