diff options
Diffstat (limited to 'src/ctrl')
| -rw-r--r-- | src/ctrl/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | src/ctrl/include/engine/ctrl/input.h | 108 | ||||
| -rw-r--r-- | src/ctrl/include/engine/ctrl/keycodes.h | 93 | ||||
| -rw-r--r-- | src/ctrl/include/engine/ctrl/scancodes.h | 89 | ||||
| -rw-r--r-- | src/ctrl/src/input.c | 424 |
5 files changed, 0 insertions, 721 deletions
diff --git a/src/ctrl/CMakeLists.txt b/src/ctrl/CMakeLists.txt deleted file mode 100644 index f37fa6a..0000000 --- a/src/ctrl/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -add_library(daw_ctrl - src/input.c - ) - -target_compile_options(daw_ctrl PUBLIC ${BUILD_OPTS}) -target_include_directories(daw_ctrl PRIVATE ${DAW_INCLUDE_DIRS} ${GLFW_INCLUDE_DIR}) -target_link_libraries(daw_ctrl PRIVATE cglm glfw) diff --git a/src/ctrl/include/engine/ctrl/input.h b/src/ctrl/include/engine/ctrl/input.h deleted file mode 100644 index 18a6797..0000000 --- a/src/ctrl/include/engine/ctrl/input.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef ENGINE_CTRL_INPUT_H -#define ENGINE_CTRL_INPUT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <cglm/ivec2.h> -#include <engine/core/types.h> -#include <engine/ctrl/keycodes.h> - -typedef void input_callback_t(void*); -typedef i32 scancode_t; -typedef i32 keycode_t; - -typedef enum InputType { - InputType_error = 0, - InputType_action, - InputType_state, - InputType_range, /* TBD */ -} InputType; - -typedef union action_t { - InputType type; - - struct { - InputType type; - input_callback_t* callback; - char* callback_str; - } action; - - struct { - InputType type; - input_callback_t* activate; - input_callback_t* deactivate; - char* activate_str; - char* deactivate_str; - } state; -} action_t; - -typedef struct binding_t { - action_t action; - - // Change type depending on input handling back-end. like u16 for GLFW_KEY - keycode_t keycode; - keycode_t keycode_alt; - - u64 since_last_activation; -} binding_t; - -typedef struct i_ctx { - - // Current mouse position - ivec2 mouse_pos; - - usize len; - binding_t* bindings; -} i_ctx; - -void i_ctx_t_free(i_ctx* c); -/* Executes all callbacks that has been pushed onto the callstack and resets the - * callstack */ -void i_flush_bindings(u64 dt, usize numcalls, input_callback_t* c[], void* state_mem); -action_t i_get_action(const i_ctx* restrict ctx, u64 time, keycode_t keycode); - -void key_callback(void* window, int key, int scancode, int action, int mods); - -void i_ctx_push(i_ctx* ctx); -void i_ctx_pop(void); -void i_ctx_reset(void); - -/* Finds and updates the keycode of a binding with the given action in ctx */ -void i_bind_ctx(i_ctx* c, keycode_t s, action_t* a); -void i_bind_ctx_alt(i_ctx* c, keycode_t s, action_t* a); - -/* Update the keycode of a binding */ -void i_bind(binding_t* b, keycode_t s); -void i_bind_alt(binding_t* b, keycode_t s); - -#define BindAction(key, altkey, f_action) \ - (binding_t) { \ - .action = (action_t){.action = \ - { \ - .type = InputType_action, \ - .callback = (input_callback_t*)&f_action, \ - .callback_str = strdup(#f_action), \ - }}, \ - .keycode = key, .keycode_alt = altkey, .since_last_activation = 0 \ - } - -#define BindState(key, altkey, f_activate, f_deactivate) \ - (binding_t) { \ - .action = \ - (action_t){.state = \ - { \ - .type = InputType_state, \ - .activate = (input_callback_t*)&f_activate, \ - .deactivate = (input_callback_t*)&f_deactivate, \ - .activate_str = strdup(#f_activate), \ - .deactivate_str = strdup(#f_deactivate), \ - }}, \ - .keycode = key, .keycode_alt = altkey, .since_last_activation = 0 \ - } - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/ctrl/include/engine/ctrl/keycodes.h b/src/ctrl/include/engine/ctrl/keycodes.h deleted file mode 100644 index 4fff38e..0000000 --- a/src/ctrl/include/engine/ctrl/keycodes.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef ENGINE_CTRL_SCANCODES_H - -#ifdef __cplusplus -extern "C" { -#endif - -// We want to reserve the following bytes marked with X for MODS, -// one bit per MODIFIER (shift, control, alt, super): -// XXXX 0000 0000 0000 0000 0000 0000 0000 -// -// We want to reserve the following bytes marked with X for ACTIONS -// enumerate by action type, pressed, released, repeat -// 0000 0000 XXXX 0000 0000 0000 0000 0000 -// -// We want to reserve the following bytes marked with X for the KEYCODE -// 0000 0000 0000 0000 XXXX XXXX XXXX XXXX -#define KEY_MOD(x) 1 << (32-4 + x) -#define ACTION(x) (1 << (32-8)) + x - -typedef enum { - KEY_SPACE = ' ', - KEY_APOSTROPHE = '\'', - KEY_COMMA = ',', - KEY_MINUS = '-', - KEY_PERIOD = '.', - KEY_SLASH = '/', - - KEY_0 = '0', - KEY_1 = '1', - KEY_2 = '2', - KEY_3 = '3', - KEY_4 = '4', - KEY_5 = '5', - KEY_6 = '6', - KEY_7 = '7', - KEY_8 = '8', - KEY_9 = '9', - - KEY_SEMICOLON = ';', - KEY_EQUAL = '=', - - KEY_A = 'A', - KEY_B = 'B', - KEY_C = 'C', - KEY_D = 'D', - KEY_E = 'E', - KEY_F = 'F', - KEY_G = 'G', - KEY_H = 'H', - KEY_I = 'I', - KEY_J = 'J', - KEY_K = 'K', - KEY_L = 'L', - KEY_M = 'M', - KEY_N = 'N', - KEY_O = 'O', - KEY_P = 'P', - KEY_Q = 'Q', - KEY_R = 'R', - KEY_S = 'S', - KEY_T = 'T', - KEY_U = 'U', - KEY_V = 'V', - KEY_W = 'W', - KEY_X = 'X', - KEY_Y = 'Y', - KEY_Z = 'Z', - - KEY_LEFT_BRACKET = '[', - KEY_BACKSLASH = '\\', - KEY_RIGHT_BRACKET = ']', - KEY_GRAVE_ACCENT = '`', - - ACTION_PRESS = ACTION(0), - ACTION_RELEASE = ACTION(1), - ACTION_REPEAT = ACTION(2), - - MOD_SHIFT = KEY_MOD(0), - MOD_CONTROL = KEY_MOD(1), - MOD_ALT = KEY_MOD(2), - MOD_SUPER = KEY_MOD(3), -} KeyCode; -#define MOD_SHFT MOD_SHIFT -#define MOD_CTRL MOD_CONTROL -#define MOD_SUPR MOD_SUPER - -#undef ACTION -#undef KEY_MOD - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/ctrl/include/engine/ctrl/scancodes.h b/src/ctrl/include/engine/ctrl/scancodes.h deleted file mode 100644 index 5b18833..0000000 --- a/src/ctrl/include/engine/ctrl/scancodes.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef ENGINE_CTRL_SCANCODES_H - -#ifdef __cplusplus -extern "C" { -#endif - -// We want to reserve the following bytes marked with X for MODS, -// one bit per MODIFIER (shift, control, alt, super): -// XXXX 0000 0000 0000 0000 0000 0000 0000 -// -// We want to reserve the following bytes marked with X for ACTIONS -// enumerate by action type, pressed, released, repeat -// 0000 0000 XXXX 0000 0000 0000 0000 0000 -// -// We want to reserve the following bytes marked with X for the SCANCODE -// 0000 0000 0000 0000 XXXX XXXX XXXX XXXX -#define MOD(x) 1 << (32-4 + x) -#define ACTION(x) (1 << (32-8)) + x - -typedef enum { - SCAN_KEY_SPACE = ' ', - SCAN_KEY_APOSTROPHE = '\'', - SCAN_KEY_COMMA = ',', - SCAN_KEY_MINUS = '-', - SCAN_KEY_PERIOD = '.', - SCAN_KEY_SLASH = '/', - - SCAN_KEY_0 = '0', - SCAN_KEY_1 = '1', - SCAN_KEY_2 = '2', - SCAN_KEY_3 = '3', - SCAN_KEY_4 = '4', - SCAN_KEY_5 = '5', - SCAN_KEY_6 = '6', - SCAN_KEY_7 = '7', - SCAN_KEY_8 = '8', - SCAN_KEY_9 = '9', - - SCAN_KEY_SEMICOLON = ';', - SCAN_KEY_EQUAL = '=', - - SCAN_KEY_A = 'A', - SCAN_KEY_B = 'B', - SCAN_KEY_C = 'C', - SCAN_KEY_D = 'D', - SCAN_KEY_E = 'E', - SCAN_KEY_F = 'F', - SCAN_KEY_G = 'G', - SCAN_KEY_H = 'H', - SCAN_KEY_I = 'I', - SCAN_KEY_J = 'J', - SCAN_KEY_K = 'K', - SCAN_KEY_L = 'L', - SCAN_KEY_M = 'M', - SCAN_KEY_N = 'N', - SCAN_KEY_O = 'O', - SCAN_KEY_P = 'P', - SCAN_KEY_Q = 'Q', - SCAN_KEY_R = 'R', - SCAN_KEY_S = 'S', - SCAN_KEY_T = 'T', - SCAN_KEY_U = 'U', - SCAN_KEY_V = 'V', - SCAN_KEY_W = 'W', - SCAN_KEY_X = 'X', - SCAN_KEY_Y = 'Y', - SCAN_KEY_Z = 'Z', - - SCAN_KEY_LEFT_BRACKET = '[', - SCAN_KEY_BACKSLASH = '\\', - SCAN_KEY_RIGHT_BRACKET = ']', - SCAN_KEY_GRAVE_ACCENT = '`', - - SCAN_ACTION_PRESS = ACTION(0), - SCAN_ACTION_RELEASE = ACTION(1), - SCAN_ACTION_REPEAT = ACTION(2), - - SCAN_MOD_SHIFT = MOD(0), - SCAN_MOD_CONTROL = MOD(1), - SCAN_MOD_ALT = MOD(2), - SCAN_MOD_SUPER = MOD(3), -} ScanCode; -#undef ACTION -#undef MOD - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/ctrl/src/input.c b/src/ctrl/src/input.c deleted file mode 100644 index 52d5ce4..0000000 --- a/src/ctrl/src/input.c +++ /dev/null @@ -1,424 +0,0 @@ -#include <errno.h> -#include <string.h> - -#undef GLFW_INCLUDE_NONE -#include <GLFW/glfw3.h> - -#include <engine/core/dltools.h> -#include <engine/core/logging.h> -#include <engine/core/platform.h> -#include <engine/ctrl/input.h> - -extern input_callback_t* callbacks[128]; -extern usize callbacks_len; - -extern Instance* GLOBAL_PLATFORM; -/* Lazy binds, used internally. They are similar to BindAction and friends. - * The only difference is that we set callbacks and such to NULL, but populate - * the function name strings such that can be reloaded. */ -#define BindActionLazy(key, altkey, action_str) \ - (binding_t) { \ - .action = (action_t){.action = \ - { \ - .type = InputType_action, \ - .callback = NULL, \ - .callback_str = strdup(action_str), \ - }}, \ - .keycode = key, .keycode_alt = altkey, .since_last_activation = 0 \ - } - -#define BindStateLazy(key, altkey, _activate_str, _deactivate_str) \ - (binding_t) { \ - .action = (action_t){.state = \ - { \ - .type = InputType_state, \ - .activate = NULL, \ - .deactivate = NULL, \ - .activate_str = strdup(_activate_str), \ - .deactivate_str = strdup(_deactivate_str), \ - }}, \ - .keycode = key, .keycode_alt = altkey, .since_last_activation = 0 \ - } - -void key_callback(void* window, int key, int scancode, int action, int mods) { - - const i_ctx* bindings = *GLOBAL_PLATFORM->window->bindings; - const usize bindings_len = GLOBAL_PLATFORM->window->bindings_len; - - const u64 now = get_time(); - - for (usize b = 0; b < bindings_len; b++) { - const action_t a = i_get_action(&bindings[b], now, key); - switch (action) { - case GLFW_PRESS: - - switch (a.type) { - case InputType_action: - if (a.action.callback != NULL) { - callbacks[callbacks_len++] = a.action.callback; - } - break; - - case InputType_state: - if (a.state.activate != NULL) { - callbacks[callbacks_len++] = a.state.activate; - } - break; - case InputType_range: -#ifdef _DEBUG - WARN("Range inputs not supported yet!"); -#endif - break; - case InputType_error: -#ifdef _DEBUG - WARN("Unhandled keycode: %lu", key); -#endif - - default: - break; - } - break; - - case GLFW_RELEASE: - switch (a.type) { - case InputType_state: - if (a.state.deactivate != NULL) { - callbacks[callbacks_len++] = a.state.deactivate; - } - break; - default:break; - } - break; - case GLFW_REPEAT: - /* unhandled so far */ - break; - default: - break; - } - } -} - -void binding_t_free(binding_t* b) { - switch (b->action.type) { - case InputType_error: - ERROR("Cannot free binding of type InputType_error"); - break; - case InputType_action: - free(b->action.action.callback_str); - return; - - case InputType_state: - free(b->action.state.activate_str); - free(b->action.state.deactivate_str); - break; - - case InputType_range: - ERROR("Cannot free binding of type InputType_rage"); - break; - - default: - ERROR("Unknown bindings type"); - break; - } - exit(EXIT_FAILURE); -} - -void i_ctx_t_free(i_ctx* c) { - for (usize i = 0; i < c->len; i++) { - binding_t_free(&c->bindings[i]); - } -} - -bool binding_action_cmp(binding_t* restrict a, binding_t* restrict b) { - InputType t = a->action.type; - if (t != b->action.type) return false; - switch (t) { - case InputType_action: - return !strcmp(a->action.action.callback_str, - b->action.action.callback_str); - - case InputType_state: - return (!strcmp(a->action.state.activate_str, - b->action.state.activate_str)) && - (!strcmp(a->action.state.deactivate_str, - b->action.state.deactivate_str)); - - case InputType_range: // fallthrough - default: - return false; // not implemented - } - return false; -} - -bool binding_keycode_cmp(binding_t* restrict a, binding_t* restrict b) { - return a->keycode == b->keycode || a->keycode_alt == b->keycode_alt; -} - -bool binding_keycode_cmp_i(binding_t* restrict a, keycode_t keycode) { - return a->keycode == keycode || a->keycode_alt == keycode; -} - -// If any binding in ctx contains action, replace that entry. -bool i_update_binding(i_ctx* ctx, binding_t* binding) { - usize idx = 0; - if (ctx == NULL || binding == NULL) { - ERROR("i_update_binding received nullptr!"); - return false; - } - - while (idx < ctx->len && !binding_action_cmp(&ctx->bindings[idx], binding)) - idx++; - - if (idx < ctx->len && binding_action_cmp(&ctx->bindings[idx], binding)) { - ctx->bindings[idx].keycode = binding->keycode; - ctx->bindings[idx].keycode_alt = binding->keycode_alt; - return true; - } - - return false; -} - -// If any binding in ctx contains keycode, replace that action. -bool i_update_unique_binding(i_ctx* ctx, binding_t* binding) { - usize idx = 0; - if (ctx == NULL || binding == NULL) { - ERROR("i_update_unique_binding received nullptr!"); - return false; - } - - while (idx < ctx->len && !binding_keycode_cmp(&ctx->bindings[idx], binding)) - idx++; - - if (idx < ctx->len && binding_keycode_cmp(&ctx->bindings[idx], binding)) { - ctx->bindings[idx].action = binding->action; - return true; - } - - return false; -} - -/* Call binding callbacks of respective bindings */ -void i_flush_bindings(u64 dt, usize numcalls, input_callback_t* c[], void* state_mem) { - for (usize i = 0; i < numcalls; i++) { - (c[i])(state_mem); - } - - // reset callback len and be ready for more - callbacks_len = 0; -} - -action_t i_get_action(const i_ctx* restrict ctx, u64 time, - keycode_t keycode) { - usize idx = 0; - - if (ctx == NULL) { - ERROR("%s received nullptr!", __func__); - return (action_t){.type = InputType_error}; - } - - // Needed for glfw - switch (keycode) { - case GLFW_KEY_LEFT_SHIFT: - case GLFW_KEY_RIGHT_SHIFT: - keycode = MOD_SHIFT; - break; - - case GLFW_KEY_LEFT_CONTROL: - case GLFW_KEY_RIGHT_CONTROL: - keycode = MOD_CONTROL; - break; - - case GLFW_KEY_LEFT_ALT: - case GLFW_KEY_RIGHT_ALT: - keycode = MOD_ALT; - break; - - case GLFW_KEY_LEFT_SUPER: - case GLFW_KEY_RIGHT_SUPER: - keycode = MOD_SUPER; - break; - - default: break; - } - - while (idx < ctx->len && - !binding_keycode_cmp_i(&ctx->bindings[idx], keycode)) - idx++; - - if (idx < ctx->len && binding_keycode_cmp_i(&ctx->bindings[idx], keycode)) { - ctx->bindings[idx].since_last_activation = time; - return ctx->bindings[idx].action; - } - - return (action_t){.type = InputType_error}; -} - -/* Make a lazy duplication of a binding. See comments on BindActionLazy and - * friends above. */ -i_ctx* i_ctx_dup(i_ctx** ctx, usize ctx_len) { - usize num_binds = 0; - for (usize c = 0; c < ctx_len; c++) { - num_binds += ctx[c]->len; - } - - binding_t* bb = calloc(num_binds, sizeof(binding_t)); - i_ctx* ret = calloc(ctx_len, sizeof(i_ctx)); - - usize cumsum = 0; - for (usize c = 0; c < ctx_len; c++) { - binding_t* b = ctx[c]->bindings; - ret[c].len = ctx[c]->len; - ret[c].bindings = &bb[cumsum]; - - for (usize i = 0; i < ctx[c]->len; i++) { - switch (b[i].action.type) { - case InputType_error: - break; - case InputType_action: - bb[cumsum] = BindActionLazy(b[i].keycode, b[i].keycode_alt, - strdup(b[i].action.action.callback_str)); - break; - case InputType_state: - bb[cumsum] = BindStateLazy(b[i].keycode, b[i].keycode_alt, - strdup(b[i].action.state.activate_str), - strdup(b[i].action.state.deactivate_str)); - break; - case InputType_range: - default: - break; - } - cumsum++; - } - } - return ret; -} - -/* Returns a pointer to a binding in c with .action == a. - * Returns NULL if not found. */ -binding_t* get_action(i_ctx* c, action_t* a) { - for (usize i = 0; i < c->len; i++) { - if (c->bindings[i].action.type != a->type) continue; - - switch (c->bindings[i].action.type) { - case InputType_error: - return NULL; - - case InputType_action: - if (!strcmp(c->bindings[i].action.action.callback_str, - a->action.callback_str)) { - return &c->bindings[i]; - } - break; - - case InputType_state: - if (!strcmp(c->bindings[i].action.state.activate_str, - a->state.activate_str) && - !strcmp(c->bindings[i].action.state.deactivate_str, - a->state.deactivate_str)) { - return &c->bindings[i]; - } - break; - - case InputType_range: - default: - return NULL; - } - } - return NULL; -} - -void i_bind_ctx(i_ctx* c, keycode_t s, action_t* a) { - binding_t* b = get_action(c, a); - - if (b == NULL) { - WARN("Failed to update keybinding"); - return; - } - - b->keycode = s; -} - -void i_bind_ctx_alt(i_ctx* c, keycode_t s, action_t* a) { - binding_t* b = get_action(c, a); - - if (b == NULL) { - WARN("Failed to update keybinding"); - return; - } - - b->keycode_alt = s; -} - -void i_bind(binding_t* b, keycode_t s) { - if (b == NULL) { - WARN("Failed to update keybinding"); - return; - } - - b->keycode = s; -} - -void i_bind_alt(binding_t* b, keycode_t s) { - if (b == NULL) { - WARN("Failed to update keybinding"); - return; - } - - b->keycode_alt = s; -} - -/* Pushes an input context onto the input handling stack */ -void i_ctx_push(i_ctx* ctx) { - if (GLOBAL_PLATFORM->window->bindings == NULL) { - GLOBAL_PLATFORM->window->bindings = calloc(8, sizeof(i_ctx*)); - GLOBAL_PLATFORM->window->bindings_sz = 8; - } - - if (GLOBAL_PLATFORM->window->bindings_len + 1 >= GLOBAL_PLATFORM->window->bindings_sz) { - void* m = - realloc(GLOBAL_PLATFORM->window->bindings, GLOBAL_PLATFORM->window->bindings_sz + 8); - if (m == NULL) { - ERROR("Failed to allocate 8 bytes (%d): %s", errno, strerror(errno)); - exit(EXIT_FAILURE); - } - GLOBAL_PLATFORM->window->bindings_sz += 8; - } - - LOG("Bindings in ctx[%d]:", GLOBAL_PLATFORM->window->bindings_len); - for (usize i = 0; i < ctx->len; i++) { - switch (ctx->bindings[i].action.type) { - case InputType_error: - LOG("(error)"); - break; - - case InputType_action: - LOG("(action) %s", ctx->bindings[i].action.action.callback_str); - break; - - case InputType_state: - LOG("(+state) %s", ctx->bindings[i].action.state.activate_str); - LOG("(-state) %s", ctx->bindings[i].action.state.deactivate_str); - break; - - case InputType_range: - LOG("(range) --unhandled--"); - break; - } - } - - GLOBAL_PLATFORM->window->bindings[GLOBAL_PLATFORM->window->bindings_len++] = ctx; -} - -/* Pops an input context from the input stack */ -void i_ctx_pop(void) { - if (GLOBAL_PLATFORM->window->bindings == NULL || GLOBAL_PLATFORM->window->bindings_sz == 0) - return; - i_ctx_t_free(GLOBAL_PLATFORM->window->bindings[--GLOBAL_PLATFORM->window->bindings_len]); -} - -/* Removes all input contexts from the input stack */ -void i_ctx_reset(void) { - while (GLOBAL_PLATFORM->window->bindings_len > 0) { - i_ctx_t_free(GLOBAL_PLATFORM->window->bindings[--GLOBAL_PLATFORM->window->bindings_len]); - } -} |
