package input State :: enum { Up, Pressed, Down, Released, } Keyboard_Key :: enum { Number_0, Number_1, Number_2, Number_3, Number_4, Number_5, Number_6, Number_7, Number_8, Number_9, Letter_A, Letter_B, Letter_C, Letter_D, Letter_E, Letter_F, Letter_G, Letter_H, Letter_I, Letter_J, Letter_K, Letter_L, Letter_M, Letter_N, Letter_O, Letter_P, Letter_Q, Letter_R, Letter_S, Letter_T, Letter_U, Letter_V, Letter_W, Letter_X, Letter_Y, Letter_Z, Space, Enter, Escape, Tab, Backspace, CapsLock, Shift, Control, Alt, Arrow_Up, Arrow_Down, Arrow_Left, Arrow_Right, Super, } Mouse_Button :: enum { Left, Middle, Right, // .. } Frame :: struct { keyboard: [len(Keyboard_Key)]State, mouse: [len(Mouse_Button)]State, } frame_start :: proc(current, previous: ^Frame) { // Compare current with previous. // If a key was 'Pressed' last frame, it should be 'Down' now. // If a key was 'Released' last frame, it should be 'Up' now. for state, i in previous.keyboard { if state == .Pressed { current.keyboard[i] = .Down } else if state == .Released { current.keyboard[i] = .Up } } for state, i in previous.mouse { if state == .Pressed { current.mouse[i] = .Down } else if state == .Released { current.mouse[i] = .Up } } } frame_end :: proc(current, previous: ^Frame) { previous^ = current^ } register_key_down :: proc(frame: ^Frame, key: Keyboard_Key) { prev := frame.keyboard[key] if prev == .Up || prev == .Released { frame.keyboard[key] = .Pressed } else { frame.keyboard[key] = .Down } } register_key_up :: proc(frame: ^Frame, key: Keyboard_Key) { prev := frame.keyboard[key] if prev == .Down || prev == .Pressed { frame.keyboard[key] = .Released } else { frame.keyboard[key] = .Up } } register_mouse_down :: proc(frame: ^Frame, button: Mouse_Button) { prev := frame.mouse[button] if prev == .Up || prev == .Released { frame.mouse[button] = .Pressed } else { frame.mouse[button] = .Down } } register_mouse_up :: proc(frame: ^Frame, button: Mouse_Button) { prev := frame.mouse[button] if prev == .Down || prev == .Pressed { frame.mouse[button] = .Released } else { frame.mouse[button] = .Up } } is_key :: proc(key: Keyboard_Key, state: bit_set[State], frame: ^Frame) -> bool { return frame.keyboard[key] in state } is_mouse :: proc(button: Mouse_Button, state: bit_set[State], frame: ^Frame) -> bool { return frame.mouse[button] in state } state_key :: proc(key: Keyboard_Key, frame: ^Frame) -> State { return frame.keyboard[key] } state_mouse :: proc(button: Mouse_Button, frame: ^Frame) -> State { return frame.mouse[button] }