Baseline input and replay setup done. Needs testing and fixes
This commit is contained in:
		
							
								
								
									
										119
									
								
								code/api.odin
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								code/api.odin
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | ||||
| package sectr | ||||
|  | ||||
| import    "base:runtime" | ||||
| import    "core:dynlib" | ||||
| import    "core:fmt" | ||||
| import    "core:mem" | ||||
| @@ -9,7 +10,8 @@ import    "core:slice" | ||||
| import    "core:strings" | ||||
| import rl "vendor:raylib" | ||||
|  | ||||
| Path_Assets :: "../assets/" | ||||
| Path_Assets       :: "../assets/" | ||||
| Path_Input_Replay :: "scratch.sectr_replay" | ||||
|  | ||||
| ModuleAPI :: struct { | ||||
| 	lib         : dynlib.Library, | ||||
| @@ -25,7 +27,7 @@ ModuleAPI :: struct { | ||||
| } | ||||
|  | ||||
| @export | ||||
| startup :: proc( live_mem, snapshot_mem : ^ virtual.Arena ) | ||||
| startup :: proc( live_mem : virtual.Arena, snapshot_mem : []u8 ) | ||||
| { | ||||
| 	// Setup memory for the first time | ||||
| 	{ | ||||
| @@ -51,6 +53,9 @@ startup :: proc( live_mem, snapshot_mem : ^ virtual.Arena ) | ||||
| 	state := new( State, tracked_allocator( memory.persistent ) ) | ||||
| 	using state | ||||
|  | ||||
| 	input      = & input_data[1] | ||||
| 	input_prev = & input_data[0] | ||||
|  | ||||
| 	// Rough setup of window with rl stuff | ||||
| 	screen_width  = 1280 | ||||
| 	screen_height = 1000 | ||||
| @@ -58,7 +63,7 @@ startup :: proc( live_mem, snapshot_mem : ^ virtual.Arena ) | ||||
| 	rl.InitWindow( screen_width, screen_height, win_title ) | ||||
|  | ||||
| 	// Determining current monitor and setting the target frametime based on it.. | ||||
| 	monitor_id         = rl.GetCurrentMonitor() | ||||
| 	monitor_id         = rl.GetCurrentMonitor    () | ||||
| 	monitor_refresh_hz = rl.GetMonitorRefreshRate( monitor_id ) | ||||
| 	rl.SetTargetFPS( monitor_refresh_hz ) | ||||
| 	fmt.println( "Set target FPS to: %v", monitor_refresh_hz ) | ||||
| @@ -83,12 +88,21 @@ sectr_shutdown :: proc() | ||||
| 		return | ||||
| 	} | ||||
| 	state := get_state() | ||||
| 	rl.UnloadFont( state.font_rec_mono_semicasual_reg ) | ||||
| 	rl.CloseWindow() | ||||
|  | ||||
| 	// Replay | ||||
| 	{ | ||||
| 		os.close( state.replay.active_file ) | ||||
| 	} | ||||
|  | ||||
| 	// Raylib | ||||
| 	{ | ||||
| 		rl.UnloadFont ( state.font_rec_mono_semicasual_reg ) | ||||
| 		rl.CloseWindow() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @export | ||||
| reload :: proc( live_mem, snapshot_mem : ^ virtual.Arena ) | ||||
| reload :: proc( live_mem : virtual.Arena, snapshot_mem : []u8 ) | ||||
| { | ||||
| 	using memory; | ||||
| 	block := live_mem.curr_block | ||||
| @@ -100,6 +114,13 @@ reload :: proc( live_mem, snapshot_mem : ^ virtual.Arena ) | ||||
| 	persistent = cast( ^TrackedAllocator ) & persistent_slice[0] | ||||
| 	transient  = cast( ^TrackedAllocator ) & transient_slice[0] | ||||
| 	temp       = cast( ^TrackedAllocator ) & temp_slice[0] | ||||
|  | ||||
| 	snapshot = snapshot_mem | ||||
| } | ||||
|  | ||||
| // TODO(Ed) : This lang really not have a fucking swap? | ||||
| swap :: proc( a, b : ^ $Type ) -> ( ^ Type, ^ Type ) { | ||||
| 	return b, a | ||||
| } | ||||
|  | ||||
| @export | ||||
| @@ -107,6 +128,56 @@ update :: proc() -> b32 | ||||
| { | ||||
| 	state := get_state(); using state | ||||
|  | ||||
| 	state.input, state.input_prev = swap( state.input, state.input_prev ) | ||||
| 	poll_input( state.input_prev, state.input ) | ||||
|  | ||||
| 	debug_actions : DebugActions | ||||
| 	poll_debug_actions( & debug_actions, state.input ) | ||||
|  | ||||
| 	// Input Replay | ||||
| 	{ | ||||
| 		if debug_actions.record_replay { #partial switch replay.mode | ||||
| 		{ | ||||
| 			case ReplayMode.Off : { | ||||
| 				save_snapshot( & memory.snapshot[0] ) | ||||
| 				replay_recording_begin( Path_Input_Replay ) | ||||
| 			} | ||||
| 			case ReplayMode.Record : { | ||||
| 				replay_recording_end() | ||||
| 			} | ||||
| 		}} | ||||
|  | ||||
| 		if debug_actions.play_replay { switch replay.mode | ||||
| 		{ | ||||
| 			case ReplayMode.Off : { | ||||
| 				replay_playback_begin( Path_Input_Replay ) | ||||
| 			} | ||||
| 			case ReplayMode.Playback : { | ||||
| 				replay_playback_end() | ||||
| 				load_snapshot( & memory.snapshot[0] ) | ||||
| 			} | ||||
| 			case ReplayMode.Record : { | ||||
| 				replay_recording_end( ) | ||||
| 				load_snapshot( & memory.snapshot[0] ) | ||||
| 				replay_playback_begin( Path_Input_Replay ) | ||||
| 			} | ||||
| 		}} | ||||
|  | ||||
| 		if replay.loop_active | ||||
| 		{ | ||||
| 			if replay.mode == ReplayMode.Record { | ||||
| 				record_input( replay.active_file, input ) | ||||
| 			} | ||||
| 			else if replay.mode == ReplayMode.Playback { | ||||
| 				play_input( replay.active_file, input ) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if debug_actions.show_mouse_pos { | ||||
| 		debug.mouse_vis = !debug.mouse_vis | ||||
| 	} | ||||
|  | ||||
| 	should_shutdown : b32 = ! cast(b32) rl.WindowShouldClose() | ||||
| 	return should_shutdown | ||||
| } | ||||
| @@ -129,20 +200,39 @@ render :: proc() | ||||
| 		@static draw_text_scratch : [Kilobyte * 64]u8 | ||||
|  | ||||
| 		state := get_state(); using state | ||||
| 		if ( draw_debug_text_y > 800 ) { | ||||
| 			draw_debug_text_y = 50 | ||||
| 		if debug.draw_debug_text_y > 800 { | ||||
| 			debug.draw_debug_text_y = 50 | ||||
| 		} | ||||
|  | ||||
| 		content := fmt.bprintf( draw_text_scratch[:], format, ..args ) | ||||
| 		debug_text( content, 25, draw_debug_text_y ) | ||||
| 		debug_text( content, 25, debug.draw_debug_text_y ) | ||||
|  | ||||
| 		draw_debug_text_y += 16 | ||||
| 		debug.draw_debug_text_y += 16 | ||||
| 	} | ||||
|  | ||||
| 	draw_text( "Screen Width : %v", rl.GetScreenWidth() ) | ||||
| 	draw_text( "Screen Width : %v", rl.GetScreenWidth () ) | ||||
| 	draw_text( "Screen Height: %v", rl.GetScreenHeight() ) | ||||
|  | ||||
| 	draw_debug_text_y = 50 | ||||
| 	if pressed( input.keyboard.M ) { | ||||
| 		draw_text( "M Prssed" ) | ||||
| 	} | ||||
| 	if pressed( input.keyboard.right_alt ) { | ||||
| 		draw_text( "Alt Pressed") | ||||
| 	} | ||||
|  | ||||
| 	if debug.mouse_vis { | ||||
| 		width : f32 = 32 | ||||
| 		pos   := debug.mouse_pos | ||||
|  | ||||
| 		mouse_rect : rl.Rectangle | ||||
| 		mouse_rect.x      = pos.x - width/2 | ||||
| 		mouse_rect.y      = pos.y - width/2 | ||||
| 		mouse_rect.width  = width | ||||
| 		mouse_rect.height = width | ||||
| 		rl.DrawRectangleRec( mouse_rect, Color_White ) | ||||
| 	} | ||||
|  | ||||
| 	debug.draw_debug_text_y = 50 | ||||
| } | ||||
|  | ||||
| @export | ||||
| @@ -150,8 +240,3 @@ clean_temp :: proc() | ||||
| { | ||||
| 	mem.tracking_allocator_clear( & memory.temp.tracker ) | ||||
| } | ||||
|  | ||||
| get_state :: proc() -> (^ State) | ||||
| { | ||||
| 	return cast(^ State) raw_data( memory.persistent.backing.data ) | ||||
| } | ||||
|   | ||||
| @@ -4,6 +4,8 @@ import rl "vendor:raylib" | ||||
|  | ||||
| Color :: rl.Color | ||||
|  | ||||
| Color_White :: rl.WHITE | ||||
|  | ||||
| Color_BG           :: Color {  41,  41,  45, 255 } | ||||
| Color_BG_TextBox   :: Color {  32,  32,  32, 255 } | ||||
| Color_Frame_Hover  :: Color { 122, 122, 125, 255 } | ||||
|   | ||||
							
								
								
									
										145
									
								
								code/env.odin
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								code/env.odin
									
									
									
									
									
								
							| @@ -1,6 +1,12 @@ | ||||
| package sectr | ||||
|  | ||||
| import "base:runtime" | ||||
| import "core:fmt" | ||||
| import "core:mem" | ||||
| import "core:mem/virtual" | ||||
| import "core:os" | ||||
|  | ||||
| import rl "vendor:raylib" | ||||
|  | ||||
| memory : Memory | ||||
|  | ||||
| @@ -9,15 +15,22 @@ memory_persistent_size :: 128 * Megabyte | ||||
| memory_trans_temp_size :: (memory_chunk_size - memory_persistent_size ) / 2 | ||||
|  | ||||
| Memory :: struct { | ||||
| 	live       : ^ virtual.Arena, | ||||
| 	snapshot   : ^ virtual.Arena, | ||||
| 	live       : virtual.Arena, | ||||
| 	snapshot   : []u8, | ||||
| 	persistent : ^ TrackedAllocator, | ||||
| 	transient  : ^ TrackedAllocator, | ||||
| 	temp       : ^ TrackedAllocator | ||||
| } | ||||
|  | ||||
|  | ||||
| State :: struct { | ||||
| 	input_data : [2] InputState, | ||||
|  | ||||
| 	input_prev : ^ InputState, | ||||
| 	input      : ^ InputState, | ||||
|  | ||||
| 	replay : ReplayState, | ||||
| 	debug  : DebugData, | ||||
|  | ||||
| 	project : Project, | ||||
|  | ||||
| 	screen_width  : i32, | ||||
| @@ -31,8 +44,6 @@ State :: struct { | ||||
|  | ||||
| 	font_rec_mono_semicasual_reg : Font, | ||||
| 	default_font                 : Font, | ||||
|  | ||||
| 	draw_debug_text_y : f32 | ||||
| } | ||||
|  | ||||
| Project :: struct { | ||||
| @@ -43,3 +54,127 @@ Project :: struct { | ||||
| Workspace :: struct { | ||||
|  | ||||
| } | ||||
|  | ||||
| get_state :: proc() -> (^ State) { | ||||
| 	return cast( ^ State ) raw_data( memory.persistent.backing.data ) | ||||
| } | ||||
|  | ||||
| DebugData :: struct { | ||||
| 	square_size : i32, | ||||
| 	square_pos  : rl.Vector2, | ||||
|  | ||||
| 	draw_debug_text_y : f32, | ||||
|  | ||||
| 	mouse_vis : b32, | ||||
| 	mouse_pos : vec3, | ||||
| } | ||||
|  | ||||
| DebugActions :: struct { | ||||
| 	pause_renderer : b32, | ||||
|  | ||||
| 	load_auto_snapshot : b32, | ||||
| 	record_replay      : b32, | ||||
| 	play_replay        : b32, | ||||
|  | ||||
| 	show_mouse_pos : b32, | ||||
| } | ||||
|  | ||||
| poll_debug_actions :: proc( actions : ^ DebugActions, input : ^ InputState ) | ||||
| { | ||||
| 	using actions | ||||
| 	using input | ||||
|  | ||||
| 	base_replay_bind := pressed(keyboard.right_alt) && pressed( keyboard.L) | ||||
| 	record_replay     = base_replay_bind && pressed(keyboard.right_shift) | ||||
| 	play_replay       = base_replay_bind | ||||
|  | ||||
| 	show_mouse_pos = pressed(keyboard.right_alt) && pressed(keyboard.M) | ||||
| } | ||||
|  | ||||
| save_snapshot :: proc( snapshot : [^]u8 ) { | ||||
| 	live_ptr := cast( ^ rawptr ) memory.live.curr_block.base | ||||
| 	mem.copy_non_overlapping( & snapshot[0], live_ptr, memory_chunk_size ) | ||||
| } | ||||
|  | ||||
| load_snapshot :: proc( snapshot : [^]u8 ) { | ||||
| 	live_ptr := cast( ^ rawptr ) memory.live.curr_block.base | ||||
| 	mem.copy_non_overlapping( live_ptr, snapshot, memory_chunk_size ) | ||||
| } | ||||
|  | ||||
| ReplayMode :: enum { | ||||
| 	Off, | ||||
| 	Record, | ||||
| 	Playback, | ||||
| } | ||||
|  | ||||
| ReplayState :: struct { | ||||
| 	loop_active : b32, | ||||
| 	mode        : ReplayMode, | ||||
| 	active_file : os.Handle | ||||
| } | ||||
|  | ||||
| replay_recording_begin :: proc( path : string ) | ||||
| { | ||||
| 	result := os.remove( path ) | ||||
| 	if ( result != os.ERROR_NONE ) | ||||
| 	{ | ||||
| 			// TODO(Ed) : Setup a proper logging interface | ||||
| 			fmt.    printf( "Failed to delete replay file before beginning a new one" ) | ||||
| 			runtime.debug_trap() | ||||
| 			os.     exit( -1 ) | ||||
| 			// TODO(Ed) : Figure out the error code enums.. | ||||
| 	} | ||||
|  | ||||
| 	replay_file, open_error := os.open( path, os.O_RDWR | os.O_CREATE ) | ||||
| 	if ( open_error != os.ERROR_NONE ) | ||||
| 	{ | ||||
| 		// TODO(Ed) : Setup a proper logging interface | ||||
| 		fmt.    printf( "Failed to create or open the replay file" ) | ||||
| 		runtime.debug_trap() | ||||
| 		os.     exit( -1 ) | ||||
| 		// TODO(Ed) : Figure out the error code enums.. | ||||
| 	} | ||||
|  | ||||
| 	state := get_state(); using state | ||||
| 	replay.active_file = replay_file | ||||
| 	replay.mode        = ReplayMode.Record | ||||
| } | ||||
|  | ||||
| replay_recording_end :: proc() { | ||||
| 	state := get_state(); using state | ||||
| 	replay.mode = ReplayMode.Off | ||||
| 	os.close( replay.active_file ) | ||||
| } | ||||
|  | ||||
| replay_playback_begin :: proc( path : string ) | ||||
| { | ||||
| 	if ! file_exists( path ) | ||||
| 	{ | ||||
| 				// TODO(Ed) : Setup a proper logging interface | ||||
| 				fmt.    printf( "Failed to create or open the replay file" ) | ||||
| 				runtime.debug_trap() | ||||
| 				os.     exit( -1 ) | ||||
| 				// TODO(Ed) : Figure out the error code enums.. | ||||
| 	} | ||||
|  | ||||
| 	replay_file, open_error := os.open( path, os.O_RDWR | os.O_CREATE ) | ||||
| 	if ( open_error != os.ERROR_NONE ) | ||||
| 	{ | ||||
| 		// TODO(Ed) : Setup a proper logging interface | ||||
| 		fmt.    printf( "Failed to create or open the replay file" ) | ||||
| 		runtime.debug_trap() | ||||
| 		os.     exit( -1 ) | ||||
| 		// TODO(Ed) : Figure out the error code enums.. | ||||
| 	} | ||||
| 	// TODO(Ed): WE need to wrap any actions that can throw a fatal like this. Files need a grime wrap. | ||||
|  | ||||
| 	state := get_state(); using state | ||||
| 	replay.active_file = replay_file | ||||
| 	replay.mode = ReplayMode.Playback | ||||
| } | ||||
|  | ||||
| replay_playback_end :: proc() { | ||||
| 	state := get_state(); using state | ||||
| 	replay.mode = ReplayMode.Off | ||||
| 	os.close( replay.active_file ) | ||||
| } | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| // TODO(Ed) : Move this to a grime package | ||||
| package sectr | ||||
|  | ||||
| import "core:fmt" | ||||
| @@ -32,7 +33,15 @@ copy_file_sync :: proc( path_src, path_dst: string ) -> b32 | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| is_file_locked :: proc( file_path: string ) -> b32 { | ||||
| file_exists :: proc ( file_path : string ) -> b32 { | ||||
| 	path_info, result := os.stat( file_path, context.temp_allocator ) | ||||
| 	if result != os.ERROR_NONE { | ||||
| 		return false | ||||
| 	} | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| is_file_locked :: proc( file_path : string ) -> b32 { | ||||
| 	handle, err := os.open(file_path, os.O_RDONLY) | ||||
| 	if err != os.ERROR_NONE { | ||||
| 			// If the error indicates the file is in use, return true. | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| package host | ||||
|  | ||||
| import       "base:runtime" | ||||
| import      "core:dynlib" | ||||
| import      "core:io" | ||||
| import      "core:fmt" | ||||
| @@ -14,7 +15,6 @@ import      "core:mem/virtual" | ||||
| 	Petabyte :: 1024 * Terabyte | ||||
| 	Exabyte  :: 1024 * Petabyte | ||||
| import       "core:os" | ||||
| import       "core:runtime" | ||||
| import       "core:strings" | ||||
| import       "core:time" | ||||
| import rl    "vendor:raylib" | ||||
| @@ -44,7 +44,7 @@ VMemChunk :: struct { | ||||
| 	host_persistent         : TrackedAllocator, | ||||
| 	host_transient          : TrackedAllocator, | ||||
| 	sectr_live              : virtual.Arena, | ||||
| 	sectr_snapshot          : virtual.Arena | ||||
| 	sectr_snapshot          : []u8 | ||||
| } | ||||
|  | ||||
| setup_memory :: proc () -> VMemChunk | ||||
| @@ -61,14 +61,45 @@ setup_memory :: proc () -> VMemChunk | ||||
| 	host_transient  = tracked_allocator_init( host_transient_size,  internals_size ) | ||||
|  | ||||
| 	// Setup the static arena for the entire application | ||||
| 	if  result := virtual.arena_init_static( & sectr_live, sectr.memory_chunk_size, sectr.memory_chunk_size ); | ||||
| 		  result != runtime.Allocator_Error.None | ||||
| 	{ | ||||
| 		// TODO(Ed) : Setup a proper logging interface | ||||
| 		fmt.    printf( "Failed to allocate memory for the sectr module" ) | ||||
| 		runtime.debug_trap() | ||||
| 		os.     exit( -1 ) | ||||
| 		// TODO(Ed) : Figure out the error code enums.. | ||||
| 		result := virtual.arena_init_static( & sectr_live, sectr.memory_chunk_size, sectr.memory_chunk_size ) | ||||
| 		if result != runtime.Allocator_Error.None | ||||
| 		{ | ||||
| 			// TODO(Ed) : Setup a proper logging interface | ||||
| 			fmt.    printf( "Failed to allocate live memory for the sectr module" ) | ||||
| 			runtime.debug_trap() | ||||
| 			os.     exit( -1 ) | ||||
| 			// TODO(Ed) : Figure out the error code enums.. | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Setup memory mapped io for snapshots | ||||
| 	{ | ||||
| 		file_resize :: os.ftruncate | ||||
|  | ||||
| 		snapshot_file, open_error := os.open( path_snapshot, os.O_RDWR | os.O_CREATE ) | ||||
| 		if ( open_error != os.ERROR_NONE ) | ||||
| 		{ | ||||
| 			// TODO(Ed) : Setup a proper logging interface | ||||
| 			fmt.    printf( "Failed to open snapshot file for the sectr module" ) | ||||
| 			runtime.debug_trap() | ||||
| 			os.     exit( -1 ) | ||||
| 			// TODO(Ed) : Figure out the error code enums.. | ||||
| 		} | ||||
| 		file_resize( snapshot_file, sectr.memory_chunk_size ) | ||||
|  | ||||
| 		map_error : virtual.Map_File_Error | ||||
| 		sectr_snapshot, map_error = virtual.map_file_from_file_descriptor( uintptr(snapshot_file), { virtual.Map_File_Flag.Read, virtual.Map_File_Flag.Write } ) | ||||
| 		if map_error != virtual.Map_File_Error.None | ||||
| 		{ | ||||
| 			// TODO(Ed) : Setup a proper logging interface | ||||
| 			fmt.    printf( "Failed to allocate snapshot memory for the sectr module" ) | ||||
| 			runtime.debug_trap() | ||||
| 			os.     exit( -1 ) | ||||
| 			// TODO(Ed) : Figure out the error code enums.. | ||||
| 		} | ||||
|  | ||||
| 		os.close(snapshot_file) | ||||
| 	} | ||||
|  | ||||
| 	// Reassign default allocators for host | ||||
| @@ -162,7 +193,7 @@ sync_sectr_api :: proc ( sectr_api : ^ sectr.ModuleAPI, memory : ^ VMemChunk ) | ||||
| 			os.exit(-1) | ||||
| 			// TODO(Ed) : Figure out the error code enums.. | ||||
| 		} | ||||
| 		sectr_api.reload( & memory.sectr_live, & memory.sectr_snapshot ) | ||||
| 		sectr_api.reload( memory.sectr_live, memory.sectr_snapshot ) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -197,7 +228,7 @@ main :: proc() | ||||
| 	running            = true; | ||||
| 	memory             = memory | ||||
| 	sectr_api          = sectr_api | ||||
| 	sectr_api.startup( & memory.sectr_live, & memory.sectr_snapshot ) | ||||
| 	sectr_api.startup( memory.sectr_live, memory.sectr_snapshot ) | ||||
|  | ||||
| 	// TODO(Ed) : This should have an end status so that we know the reason the engine stopped. | ||||
| 	for ; running ; | ||||
|   | ||||
							
								
								
									
										490
									
								
								code/input.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										490
									
								
								code/input.odin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,490 @@ | ||||
| // TODO(Ed) : This if its gets larget can be moved to its own package | ||||
| package sectr | ||||
|  | ||||
| AnalogAxis  :: f32 | ||||
| AnalogStick :: struct { | ||||
| 	X, Y : f32 | ||||
| } | ||||
|  | ||||
| DigitalBtn :: struct { | ||||
| 	half_transitions : i32, | ||||
| 	ended_down       : b32 | ||||
| } | ||||
|  | ||||
| btn_pressed :: proc( btn : DigitalBtn ) -> b32 { | ||||
| 	return btn.ended_down && btn.half_transitions > 0 | ||||
| } | ||||
|  | ||||
| pressed :: proc { | ||||
| 	btn_pressed | ||||
| } | ||||
|  | ||||
| MaxKeyboardKeys :: 256 | ||||
| KeyboardKey :: enum { | ||||
| 	null = 0x00, | ||||
|  | ||||
| 	enter         = 0x01, | ||||
| 	tab           = 0x02, | ||||
| 	space         = 0x03, | ||||
| 	bracket_open  = 0x04, | ||||
| 	bracket_close = 0x05, | ||||
| 	semicolon     = 0x06, | ||||
| 	apostrophe    = 0x07, | ||||
| 	comma         = 0x08, | ||||
| 	period        = 0x09, | ||||
|  | ||||
| 	// 0x0A | ||||
| 	// 0x0B | ||||
| 	// 0x0C | ||||
| 	// 0x0D | ||||
| 	// 0x0E | ||||
| 	// 0x0F | ||||
|  | ||||
| 	caps_lock     = 0x10, | ||||
| 	scroll_lock   = 0x11, | ||||
| 	num_lock      = 0x12, | ||||
| 	left_alt      = 0x13, | ||||
| 	left_shit     = 0x14, | ||||
| 	left_control  = 0x15, | ||||
| 	right_alt     = 0x16, | ||||
| 	right_shift   = 0x17, | ||||
| 	right_control = 0x18, | ||||
|  | ||||
| 	// 0x19 | ||||
| 	// 0x1A | ||||
| 	// 0x1B | ||||
| 	// 0x1C | ||||
| 	// 0x1D | ||||
| 	// 0x1C | ||||
| 	// 0x1D | ||||
|  | ||||
| 	escape = 0x1F, | ||||
| 	F1     = 0x20, | ||||
| 	F2     = 0x21, | ||||
| 	F3     = 0x22, | ||||
| 	F4     = 0x23, | ||||
| 	F5     = 0x24, | ||||
| 	F6     = 0x25, | ||||
| 	F7     = 0x26, | ||||
| 	F8     = 0x27, | ||||
| 	F9     = 0x28, | ||||
| 	F10    = 0x29, | ||||
| 	F11    = 0x2A, | ||||
| 	F12    = 0x2B, | ||||
|  | ||||
| 	print_screen = 0x2C, | ||||
| 	pause        = 0x2D, | ||||
| 	// = 0x2E, | ||||
|  | ||||
| 	backtick      = 0x2F, | ||||
| 	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, | ||||
| 	hyphen        = 0x3A, | ||||
| 	equals        = 0x3B, | ||||
| 	backspace     = 0x3C, | ||||
|  | ||||
| 	backslash = 0x3D, | ||||
| 	slash     = 0x3E, | ||||
|   // = 0x3F, | ||||
| 	// = 0x40, | ||||
|  | ||||
| 	A = 0x41, | ||||
| 	B = 0x42, | ||||
| 	C = 0x43, | ||||
| 	D = 0x44, | ||||
| 	E = 0x45, | ||||
| 	F = 0x46, | ||||
| 	G = 0x47, | ||||
| 	H = 0x48, | ||||
| 	I = 0x49, | ||||
| 	J = 0x4A, | ||||
| 	K = 0x4B, | ||||
| 	L = 0x4C, | ||||
| 	M = 0x4D, | ||||
| 	N = 0x4E, | ||||
| 	O = 0x4F, | ||||
| 	P = 0x50, | ||||
| 	Q = 0x51, | ||||
| 	R = 0x52, | ||||
| 	S = 0x53, | ||||
| 	T = 0x54, | ||||
| 	U = 0x55, | ||||
| 	V = 0x56, | ||||
| 	W = 0x57, | ||||
| 	X = 0x58, | ||||
| 	Y = 0x59, | ||||
| 	Z = 0x5A, | ||||
|  | ||||
| 	insert    = 0x5B, | ||||
| 	delete    = 0x5C, | ||||
| 	home      = 0x5D, | ||||
| 	end       = 0x5E, | ||||
| 	page_up   = 0x5F, | ||||
| 	page_down = 0x60, | ||||
|  | ||||
| 	npad_0        = 0x61, | ||||
| 	npad_1        = 0x62, | ||||
| 	npad_2        = 0x63, | ||||
| 	npad_3        = 0x64, | ||||
| 	npad_4        = 0x65, | ||||
| 	npad_5        = 0x66, | ||||
| 	npad_6        = 0x67, | ||||
| 	npad_7        = 0x68, | ||||
| 	npad_8        = 0x69, | ||||
| 	npad_9        = 0x6A, | ||||
| 	npad_decimal  = 0x6B, | ||||
| 	npad_equals   = 0x6C, | ||||
| 	npad_plus     = 0x6D, | ||||
| 	npad_minus    = 0x6E, | ||||
| 	npad_multiply = 0x6F, | ||||
| 	npad_divide   = 0x70, | ||||
| 	npad_enter    = 0x71, | ||||
|  | ||||
| 	count = 0x72 | ||||
| } | ||||
|  | ||||
| KeyboardState :: struct #raw_union { | ||||
| 	keys : [MaxKeyboardKeys] DigitalBtn, | ||||
| 	using individual : struct { | ||||
| 		enter, | ||||
| 		tab, | ||||
| 		space, | ||||
| 		bracket_open, | ||||
| 		bracket_close, | ||||
| 		semicolon, | ||||
| 		apostrophe, | ||||
| 		comma, | ||||
| 		period : DigitalBtn, | ||||
|  | ||||
| 		__0x0A_0x0F_Unassigned__ : [ 6 * size_of( DigitalBtn )] u8, | ||||
|  | ||||
| 		caps_lock, | ||||
| 		scroll_lock, | ||||
| 		num_lock, | ||||
| 		left_alt, | ||||
| 		left_shift, | ||||
| 		left_control, | ||||
| 		right_alt, | ||||
| 		right_shift, | ||||
| 		right_control : DigitalBtn, | ||||
|  | ||||
| 		__0x19_0x1D_Unassigned__ : [ 6 * size_of( DigitalBtn )] u8, | ||||
|  | ||||
| 		escape, | ||||
| 		F1, | ||||
| 		F2, | ||||
| 		F3, | ||||
| 		F4, | ||||
| 		F5, | ||||
| 		F6, | ||||
| 		F7, | ||||
| 		F8, | ||||
| 		F9, | ||||
| 		F10, | ||||
| 		F11, | ||||
| 		F12 : DigitalBtn, | ||||
|  | ||||
| 		print_screen, | ||||
| 		pause : DigitalBtn, | ||||
|  | ||||
| 		__0x2E_Unassigned__ : [size_of(DigitalBtn)] u8, | ||||
|  | ||||
| 		backtick, | ||||
| 		nrow_0, | ||||
| 		nrow_1, | ||||
| 		nrow_2, | ||||
| 		nrow_3, | ||||
| 		nrow_4, | ||||
| 		nrow_5, | ||||
| 		nrow_6, | ||||
| 		nrow_7, | ||||
| 		nrow_8, | ||||
| 		nrow_9, | ||||
| 		hyphen, | ||||
| 		equals, | ||||
| 		backspace : DigitalBtn, | ||||
|  | ||||
| 		backslash, | ||||
| 		slash : DigitalBtn, | ||||
|  | ||||
| 		__0x3F_0x40_Unassigned__ : [ 2 * size_of(DigitalBtn)] u8, | ||||
|  | ||||
| 		A, 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 : DigitalBtn, | ||||
|  | ||||
| 		insert, | ||||
| 		delete, | ||||
| 		home, | ||||
| 		end, | ||||
| 		page_up, | ||||
| 		page_down : DigitalBtn, | ||||
|  | ||||
| 		npad_0, | ||||
| 		npad_1, | ||||
| 		npad_2, | ||||
| 		npad_3, | ||||
| 		npad_4, | ||||
| 		npad_5, | ||||
| 		npad_6, | ||||
| 		npad_7, | ||||
| 		npad_8, | ||||
| 		npad_9, | ||||
| 		npad_decimal, | ||||
| 		npad_equals, | ||||
| 		npad_plus, | ||||
| 		npad_minus, | ||||
| 		npad_multiply, | ||||
| 		npad_divide, | ||||
| 		npad_enter : DigitalBtn | ||||
| 	} | ||||
| } | ||||
|  | ||||
| MaxMouseBtns :: 16 | ||||
| MouseBtn :: enum { | ||||
| 	Left    = 0x0, | ||||
| 	Middle  = 0x1, | ||||
| 	Right   = 0x2, | ||||
| 	Side    = 0x3, | ||||
| 	Forward = 0x4, | ||||
| 	Back    = 0x5, | ||||
| 	Extra   = 0x6, | ||||
|  | ||||
| 	count | ||||
| } | ||||
|  | ||||
| MouseState :: struct { | ||||
| 	using _ : struct #raw_union { | ||||
| 		      btns       : [16] DigitalBtn, | ||||
| 		using individual : struct { | ||||
| 			left, middle, right        : DigitalBtn, | ||||
| 			side, forward, back, extra : DigitalBtn | ||||
| 		} | ||||
| 	}, | ||||
| 	X, Y, | ||||
| 	vertical_wheel, | ||||
| 	horizontal_wheel : AnalogAxis | ||||
| } | ||||
|  | ||||
| InputState :: struct { | ||||
| 	keyboard : KeyboardState, | ||||
| 	mouse    : MouseState | ||||
| } | ||||
|  | ||||
| import    "core:os" | ||||
| import c  "core:c/libc" | ||||
| import rl "vendor:raylib" | ||||
|  | ||||
| poll_input :: proc( old, new : ^ InputState ) | ||||
| { | ||||
| 	input_process_digital_btn :: proc ( old_state, new_state : ^ DigitalBtn, is_down : b32 ) | ||||
| 	{ | ||||
| 		new_state.ended_down = is_down | ||||
| 		had_transition      := old_state.ended_down != new_state.ended_down | ||||
| 		if had_transition { | ||||
| 			new_state.half_transitions += 1 | ||||
| 		} | ||||
| 		else { | ||||
| 			new_state.half_transitions = 0 | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Keyboard | ||||
| 	{ | ||||
| 		check_range :: proc( old, new : ^ InputState, start, end : i32 ) | ||||
| 		{ | ||||
| 			for id := start; id < end; id += 1 { | ||||
| 				// TODO(Ed) : LOOK OVER THIS... | ||||
| 				entry_old := & old.keyboard.keys[id - 1] | ||||
| 				entry_new := & new.keyboard.keys[id - 1] | ||||
|  | ||||
| 				key_id := cast(KeyboardKey) id | ||||
|  | ||||
| 				is_down := cast(b32) rl.IsKeyDown( to_raylib_key(id) ) | ||||
| 				if is_down { | ||||
| 					nothing := true | ||||
| 					nothing = false | ||||
| 				} | ||||
| 				input_process_digital_btn( entry_old, entry_new, is_down ) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		DeadBound_1 :: 0x0A | ||||
| 		DeadBound_2 :: 0x2E | ||||
| 		DeadBound_3 :: 0x19 | ||||
| 		DeadBound_4 :: 0x3F | ||||
| 		check_range( old, new, cast(i32) KeyboardKey.enter,     DeadBound_1 ) | ||||
| 		check_range( old, new, cast(i32) KeyboardKey.caps_lock, DeadBound_2 ) | ||||
| 		check_range( old, new, cast(i32) KeyboardKey.escape,    DeadBound_3 ) | ||||
| 		check_range( old, new, cast(i32) KeyboardKey.backtick,  DeadBound_4 ) | ||||
| 		check_range( old, new, cast(i32) KeyboardKey.A,         cast(i32) KeyboardKey.count ) | ||||
| 	} | ||||
|  | ||||
| 	// Mouse | ||||
| 	{ | ||||
| 		// Process Buttons | ||||
| 		for id : i32 = 0; id < i32(MouseBtn.count); id += 1 { | ||||
| 			old_btn := & old.mouse.btns[id] | ||||
| 			new_btn := & new.mouse.btns[id] | ||||
|  | ||||
| 			mouse_id := cast(MouseBtn) id | ||||
|  | ||||
| 			is_down := cast(b32) rl.IsMouseButtonPressed( to_raylib_mouse_btn(id) ) | ||||
| 			input_process_digital_btn( & old.mouse.left, & new.mouse.left, is_down ) | ||||
| 		} | ||||
|  | ||||
| 		mouse_pos := rl.GetMousePosition() | ||||
|  | ||||
| 		new.mouse.X = mouse_pos.x | ||||
| 		new.mouse.Y = mouse_pos.y | ||||
| 	} | ||||
| } | ||||
|  | ||||
| record_input :: proc( replay_file : os.Handle, input : ^ InputState ) { | ||||
| 	raw_data := slice_ptr( transmute(^ byte) input, size_of(InputState) ) | ||||
| 	os.write( replay_file, raw_data ) | ||||
| } | ||||
|  | ||||
| play_input :: proc( replay_file : os.Handle, input : ^ InputState ) { | ||||
| 	raw_data := slice_ptr( transmute(^ byte) input, size_of(InputState) ) | ||||
| 	os.read( replay_file, raw_data ) | ||||
| } | ||||
|  | ||||
| to_raylib_key :: proc ( key : i32 ) -> rl.KeyboardKey { | ||||
| 	@static raylib_key_lookup_table := [?] rl.KeyboardKey { | ||||
| 		rl.KeyboardKey.KEY_NULL, | ||||
| 		rl.KeyboardKey.ENTER, | ||||
| 		rl.KeyboardKey.TAB, | ||||
| 		rl.KeyboardKey.SPACE, | ||||
| 		rl.KeyboardKey.LEFT_BRACKET, | ||||
| 		rl.KeyboardKey.RIGHT_BRACKET, | ||||
| 		rl.KeyboardKey.SEMICOLON, | ||||
| 		rl.KeyboardKey.APOSTROPHE, | ||||
| 		rl.KeyboardKey.COMMA, | ||||
| 		rl.KeyboardKey.PERIOD, | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0A | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0B | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0C | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0D | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0E | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0F | ||||
| 		rl.KeyboardKey.CAPS_LOCK, | ||||
| 		rl.KeyboardKey.SCROLL_LOCK, | ||||
| 		rl.KeyboardKey.NUM_LOCK, | ||||
| 		rl.KeyboardKey.LEFT_ALT, | ||||
| 		rl.KeyboardKey.LEFT_SHIFT, | ||||
| 		rl.KeyboardKey.LEFT_CONTROL, | ||||
| 		rl.KeyboardKey.RIGHT_ALT, | ||||
| 		rl.KeyboardKey.RIGHT_SHIFT, | ||||
| 		rl.KeyboardKey.RIGHT_CONTROL, | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0F | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0F | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0F | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0F | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0F | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0F | ||||
| 		cast(rl.KeyboardKey) 0, // 0x0F | ||||
| 		rl.KeyboardKey.ESCAPE, | ||||
| 		rl.KeyboardKey.F1, | ||||
| 		rl.KeyboardKey.F2, | ||||
| 		rl.KeyboardKey.F3, | ||||
| 		rl.KeyboardKey.F4, | ||||
| 		rl.KeyboardKey.F5, | ||||
| 		rl.KeyboardKey.F7, | ||||
| 		rl.KeyboardKey.F8, | ||||
| 		rl.KeyboardKey.F9, | ||||
| 		rl.KeyboardKey.F10, | ||||
| 		rl.KeyboardKey.F11, | ||||
| 		rl.KeyboardKey.F12, | ||||
| 		rl.KeyboardKey.PRINT_SCREEN, | ||||
| 		rl.KeyboardKey.PAUSE, | ||||
| 		cast(rl.KeyboardKey) 0, // 0x2E | ||||
| 		rl.KeyboardKey.GRAVE, | ||||
| 		cast(rl.KeyboardKey) '0', | ||||
| 		cast(rl.KeyboardKey) '1', | ||||
| 		cast(rl.KeyboardKey) '2', | ||||
| 		cast(rl.KeyboardKey) '3', | ||||
| 		cast(rl.KeyboardKey) '4', | ||||
| 		cast(rl.KeyboardKey) '5', | ||||
| 		cast(rl.KeyboardKey) '6', | ||||
| 		cast(rl.KeyboardKey) '7', | ||||
| 		cast(rl.KeyboardKey) '8', | ||||
| 		cast(rl.KeyboardKey) '9', | ||||
| 		rl.KeyboardKey.MINUS, | ||||
| 		rl.KeyboardKey.EQUAL, | ||||
| 		rl.KeyboardKey.BACKSPACE, | ||||
| 		rl.KeyboardKey.BACKSLASH, | ||||
| 		rl.KeyboardKey.SLASH, | ||||
| 		cast(rl.KeyboardKey) 0, // 0x3F | ||||
| 		cast(rl.KeyboardKey) 0, // 0x40 | ||||
| 		rl.KeyboardKey.A, | ||||
| 		rl.KeyboardKey.B, | ||||
| 		rl.KeyboardKey.C, | ||||
| 		rl.KeyboardKey.D, | ||||
| 		rl.KeyboardKey.E, | ||||
| 		rl.KeyboardKey.F, | ||||
| 		rl.KeyboardKey.G, | ||||
| 		rl.KeyboardKey.H, | ||||
| 		rl.KeyboardKey.I, | ||||
| 		rl.KeyboardKey.J, | ||||
| 		rl.KeyboardKey.K, | ||||
| 		rl.KeyboardKey.L, | ||||
| 		rl.KeyboardKey.M, | ||||
| 		rl.KeyboardKey.N, | ||||
| 		rl.KeyboardKey.O, | ||||
| 		rl.KeyboardKey.P, | ||||
| 		rl.KeyboardKey.Q, | ||||
| 		rl.KeyboardKey.R, | ||||
| 		rl.KeyboardKey.S, | ||||
| 		rl.KeyboardKey.T, | ||||
| 		rl.KeyboardKey.U, | ||||
| 		rl.KeyboardKey.V, | ||||
| 		rl.KeyboardKey.W, | ||||
| 		rl.KeyboardKey.X, | ||||
| 		rl.KeyboardKey.Y, | ||||
| 		rl.KeyboardKey.Z, | ||||
| 		rl.KeyboardKey.INSERT, | ||||
| 		rl.KeyboardKey.DELETE, | ||||
| 		rl.KeyboardKey.HOME, | ||||
| 		rl.KeyboardKey.END, | ||||
| 		rl.KeyboardKey.PAGE_UP, | ||||
| 		rl.KeyboardKey.PAGE_DOWN, | ||||
| 		rl.KeyboardKey.KP_0, | ||||
| 		rl.KeyboardKey.KP_1, | ||||
| 		rl.KeyboardKey.KP_2, | ||||
| 		rl.KeyboardKey.KP_3, | ||||
| 		rl.KeyboardKey.KP_4, | ||||
| 		rl.KeyboardKey.KP_5, | ||||
| 		rl.KeyboardKey.KP_6, | ||||
| 		rl.KeyboardKey.KP_7, | ||||
| 		rl.KeyboardKey.KP_8, | ||||
| 		rl.KeyboardKey.KP_9, | ||||
| 		rl.KeyboardKey.KP_DECIMAL, | ||||
| 		rl.KeyboardKey.KP_EQUAL, | ||||
| 		rl.KeyboardKey.KP_ADD, | ||||
| 		rl.KeyboardKey.KP_SUBTRACT, | ||||
| 		rl.KeyboardKey.KP_MULTIPLY, | ||||
| 		rl.KeyboardKey.KP_DIVIDE, | ||||
| 		rl.KeyboardKey.KP_ENTER | ||||
| 	} | ||||
| 	return raylib_key_lookup_table[ key ] | ||||
| } | ||||
|  | ||||
| to_raylib_mouse_btn :: proc ( btn : i32 ) -> rl.MouseButton { | ||||
| 	@static raylib_mouse_btn_lookup_table := [?] rl.MouseButton { | ||||
| 		rl.MouseButton.LEFT, | ||||
| 		rl.MouseButton.MIDDLE, | ||||
| 		rl.MouseButton.RIGHT, | ||||
| 		rl.MouseButton.SIDE, | ||||
| 		rl.MouseButton.FORWARD, | ||||
| 		rl.MouseButton.BACK, | ||||
| 		rl.MouseButton.EXTRA, | ||||
| 	} | ||||
| 	return raylib_mouse_btn_lookup_table[ btn ] | ||||
| } | ||||
							
								
								
									
										18
									
								
								code/math.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								code/math.odin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| package sectr | ||||
|  | ||||
| // TODO(Ed) : Evaluate if this is needed | ||||
|  | ||||
| vec3 :: vec3_f32 | ||||
| vec3_f32 :: struct #raw_union { | ||||
| 	basis : [3] f32, | ||||
| 	using components : struct { | ||||
| 		x, y, z : f32 | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -1,3 +1,4 @@ | ||||
| // TODO(Ed) : Move this to a grime package problably | ||||
| package sectr | ||||
|  | ||||
| import "core:fmt" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user