Baseline input and replay setup done. Needs testing and fixes
This commit is contained in:
parent
f27245f7a2
commit
9b4ceeffda
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"
|
||||
|
Loading…
Reference in New Issue
Block a user