#ifndef PKE_PLAYER_INPUT_HPP #define PKE_PLAYER_INPUT_HPP #include "pk.h" #include TypeSafeInt_H(pke_input_action_set_handle, uint8_t, 0xFF); TypeSafeInt_constexpr(pke_input_action_set_flag, uint8_t, 0xFF); TypeSafeInt_constexpr(pke_input_event_hash, uint16_t, 0xFFFF); constexpr pke_input_action_set_flag PKE_INPUT_ACTION_SET_FLAG_NONE = pke_input_action_set_flag{0x00}; constexpr pke_input_action_set_flag PKE_INPUT_ACTION_SET_FLAG_DO_NOT_SERIALIZE = pke_input_action_set_flag{0x01}; constexpr pke_input_action_set_flag PKE_INPUT_ACTION_SET_FLAG_AUTO_ENABLE = pke_input_action_set_flag{0x02}; const pke_input_event_hash PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER = pke_input_event_hash {0x0001}; const pke_input_event_hash PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS = pke_input_event_hash {0x0002}; const pke_input_event_hash PKE_INPUT_HASH_EVENT_TYPE_KEY = pke_input_event_hash {0x0004}; const pke_input_event_hash PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON = pke_input_event_hash {0x0008}; const pke_input_event_hash PKE_INPUT_HASH_EVENT_TYPE_SCROLL = pke_input_event_hash {0x0010}; const pke_input_event_hash PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS = pke_input_event_hash {0x0020}; const pke_input_event_hash PKE_INPUT_HASH_CURSOR_ENTERED_FALSE = pke_input_event_hash {0x0040}; const pke_input_event_hash PKE_INPUT_HASH_CURSOR_ENTERED_TRUE = pke_input_event_hash {0x0080}; const pke_input_event_hash PKE_INPUT_HASH_KEYBOARD_KEY_ACTION_RELEASE = pke_input_event_hash{0x0100}; const pke_input_event_hash PKE_INPUT_HASH_KEYBOARD_KEY_ACTION_PRESS = pke_input_event_hash {0x0200}; const pke_input_event_hash PKE_INPUT_HASH_KEYBOARD_KEY_ACTION_REPEAT = pke_input_event_hash {0x0400}; const pke_input_event_hash PKE_INPUT_HASH_MOUSE_BUTTON_ACTION_RELEASE = pke_input_event_hash{0x0800}; const pke_input_event_hash PKE_INPUT_HASH_MOUSE_BUTTON_ACTION_PRESS = pke_input_event_hash {0x1000}; const pke_input_event_hash PKE_INPUT_HASH_WINDOW_FOCUSED_FALSE = pke_input_event_hash {0x2000}; const pke_input_event_hash PKE_INPUT_HASH_WINDOW_FOCUSED_TRUE = pke_input_event_hash {0x4000}; const pke_input_event_hash PKE_INPUT_HASH_ALL_EVENTS = PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER | PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS | PKE_INPUT_HASH_EVENT_TYPE_KEY | PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON | PKE_INPUT_HASH_EVENT_TYPE_SCROLL | PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS; const pke_input_event_hash PKE_INPUT_HASH_ALL_CURSOR_ENTER_EVENTS = PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER | PKE_INPUT_HASH_CURSOR_ENTERED_FALSE | PKE_INPUT_HASH_CURSOR_ENTERED_TRUE; const pke_input_event_hash PKE_INPUT_HASH_ALL_CURSOR_POS_EVENTS = PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS; const pke_input_event_hash PKE_INPUT_HASH_ALL_KEY_EVENTS = PKE_INPUT_HASH_EVENT_TYPE_KEY | PKE_INPUT_HASH_KEYBOARD_KEY_ACTION_RELEASE | PKE_INPUT_HASH_KEYBOARD_KEY_ACTION_PRESS | PKE_INPUT_HASH_KEYBOARD_KEY_ACTION_REPEAT; const pke_input_event_hash PKE_INPUT_HASH_ALL_MOUSE_BUTTON_EVENTS = PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON | PKE_INPUT_HASH_MOUSE_BUTTON_ACTION_RELEASE | PKE_INPUT_HASH_MOUSE_BUTTON_ACTION_PRESS; const pke_input_event_hash PKE_INPUT_HASH_ALL_SCROLL_EVENTS = PKE_INPUT_HASH_EVENT_TYPE_SCROLL; const pke_input_event_hash PKE_INPUT_HASH_ALL_WINDOW_FOCUS_EVENTS = PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS | PKE_INPUT_HASH_WINDOW_FOCUSED_FALSE | PKE_INPUT_HASH_WINDOW_FOCUSED_TRUE; struct pke_input_event { pke_input_action_set_handle sourceSet; pke_input_event_hash type; union pke_input_event_data { struct pke_input_event_cursor_enter { bool isEntered; } cursor_enter; struct pke_input_event_cursor_pos { double xMotion; double yMotion; } cursor_pos; struct pke_input_event_key { bool isPressed; bool thisTick; int32_t button; int32_t mods; } key; struct pke_input_event_mouse_button { bool isPressed; bool thisTick; int32_t button; int32_t mods; } mouse_button; struct pke_input_event_scroll { double xMotion; double yMotion; } scroll; struct pke_input_event_window_focus { bool isFocused; } window_focus; } data; }; struct pke_input_event_mask { pke_input_event_hash computedHash = pke_input_event_hash{0}; int32_t button = -1; int32_t mods = 0; }; #define PKE_INPUT_ACTION_MASK_INDEX_PRIMARY 0 #define PKE_INPUT_ACTION_MASK_INDEX_SECONDARY 1 #define PKE_INPUT_ACTION_MASK_INDEX_COUNT 2 struct pke_input_action { const char *name; pke_input_event_mask masks[2] = {{},{}}; int32_t event_indices[2] = {-1,-1}; }; struct pke_input_set { const char *title; int64_t actionCount; pke_input_action *actions; pke_input_action_set_flag flags; pk_membucket *bkt = nullptr; }; void pke_input_tick(double delta); const pke_input_event *pke_input_query_by_action_name(const char *actionName); // note: must be called from main thread (per glfw) // note: does not return `mods` nor `thisTick` // note: only supports keyboard and mouse buttons void pke_input_query_by_mask(pke_input_event_mask mask, pke_input_event &ev); void pke_input_query_mouse_pos(double &x, double &y); void pke_input_init(); pke_input_action_set_handle pke_input_register_set(const pke_input_set &&set); void pke_input_activate_set(pke_input_action_set_handle handle); void pke_input_deactivate_set(pke_input_action_set_handle handle); void pke_input_unregister_set(pke_input_action_set_handle handle); pk_arr_t &pke_input_get_input_sets(); pk_arr_t &pke_input_get_active_input_action_set_handles(); void pke_input_teardown(); #endif /* PKE_PLAYER_INPUT_HPP */