SectrPrototype/code/input/input.odin
Ed_ 40ffed9538 Changed codebase to be foldered (breaking compiler's conventions)
I now generate the layout the compiler wants, eventually I'll just have a custom policy so that the compiler can accept the non-idiomatic layout

See scripts/build.ps1 & gen_staged_compiler_codebase.ps1 for how this is handled.
2024-05-16 13:18:27 -04:00

502 lines
10 KiB
Odin

// TODO(Ed) : This if its gets larget can be moved to its own package
package sectr
import "base:runtime"
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
}
btn_released :: proc ( btn : DigitalBtn ) -> b32 {
return btn.ended_down == false && btn.half_transitions > 0
}
MaxKeyboardKeys :: 256
KeyboardKey :: enum u32 {
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 u32 {
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
}
},
raw_pos, pos, delta : Vec2,
vertical_wheel, horizontal_wheel : AnalogAxis
}
mouse_world_delta :: #force_inline proc "contextless" () -> Vec2 {
using state := get_state()
cam := & state.project.workspace.cam
return input.mouse.delta * ( 1 / cam.zoom )
}
InputState :: struct {
keyboard : KeyboardState,
mouse : MouseState
}
import "core:os"
import c "core:c/libc"
import rl "vendor:raylib"
poll_input :: proc( old, new : ^ InputState )
{
profile(#procedure)
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
{
// profile("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) )
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
{
// profile("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.IsMouseButtonDown( to_raylib_mouse_btn(id) )
input_process_digital_btn( old_btn, new_btn, is_down )
}
new.mouse.raw_pos = rl.GetMousePosition()
new.mouse.pos = render_to_screen_pos(new.mouse.raw_pos)
new.mouse.delta = rl.GetMouseDelta() * {1, -1}
new.mouse.vertical_wheel = rl.GetMouseWheelMove()
}
}
record_input :: proc( replay_file : os.Handle, input : ^ InputState ) {
raw_data := slice_ptr( transmute(^ byte) input, size_of(InputState) )
file_write( replay_file, raw_data )
}
play_input :: proc( replay_file : os.Handle, input : ^ InputState ) {
raw_data := slice_ptr( transmute(^ byte) input, size_of(InputState) )
total_read, result_code := file_read( replay_file, raw_data )
if result_code == os.ERROR_HANDLE_EOF {
file_rewind( replay_file )
load_snapshot( & Memory_App.snapshot )
}
}
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 ]
}