116 lines
2.9 KiB
C
116 lines
2.9 KiB
C
#include "input.h"
|
|
#include "debug.h"
|
|
#include <stdint.h>
|
|
|
|
typedef struct InputAction {
|
|
const uint8_t* positive;
|
|
const uint8_t* negative;
|
|
int last;
|
|
InputActionDelegate delegate;
|
|
} InputAction;
|
|
|
|
static InputAction* _actions = NULL;
|
|
static size_t _actions_len = 0;
|
|
static size_t _actions_cap = 0;
|
|
|
|
static const uint8_t* _keys;
|
|
|
|
void input_init() {
|
|
_actions = malloc(8 * sizeof(InputAction));
|
|
if(_actions == NULL) {
|
|
LOG_ERROR("Failed to allocate memory for input actions array");
|
|
return;
|
|
}
|
|
_actions_cap = 8;
|
|
|
|
_keys = SDL_GetKeyboardState(NULL);
|
|
}
|
|
|
|
void input_clean() {
|
|
free(_actions);
|
|
_actions_len = 0;
|
|
_actions_cap = 0;
|
|
}
|
|
|
|
static
|
|
void _key_changed_event(SDL_Event evt) {
|
|
const uint8_t* keyptr = _keys + evt.key.keysym.scancode;
|
|
for(InputAction* action = _actions; action < _actions + _actions_len; ++action) {
|
|
if(keyptr == action->positive || keyptr == action->negative) {
|
|
int val = *action->positive - *action->negative;
|
|
if(val != action->last) {
|
|
action->last = val;
|
|
action->delegate(val);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void input_handle_event(SDL_Event event) {
|
|
switch(event.type) {
|
|
default:return;
|
|
case SDL_KEYDOWN:
|
|
case SDL_KEYUP:
|
|
_key_changed_event(event);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static
|
|
void _resize_actions_if_needed(size_t needed_amount) {
|
|
if(_actions_cap > needed_amount)
|
|
return;
|
|
|
|
size_t next_amount = _actions_cap;
|
|
while(next_amount <= needed_amount) {
|
|
next_amount *= 2;
|
|
}
|
|
|
|
InputAction* new = realloc(_actions, next_amount);
|
|
if(new == NULL) {
|
|
LOG_ERROR("Failed to allocate enough space for adding a new input actions");
|
|
return;
|
|
}
|
|
_actions = new;
|
|
_actions_cap = next_amount;
|
|
}
|
|
|
|
void input_add_axis_action(SDL_Scancode negative, SDL_Scancode positive, InputActionDelegate delegate) {
|
|
_resize_actions_if_needed(_actions_len + 1);
|
|
_actions[_actions_len] = (InputAction){
|
|
.negative = _keys + negative,
|
|
.positive = _keys + positive,
|
|
.delegate = delegate
|
|
};
|
|
++_actions_len;
|
|
}
|
|
|
|
void input_add_key_action(SDL_Scancode key, InputActionDelegate delegate) {
|
|
_resize_actions_if_needed(_actions_len + 1);
|
|
_actions[_actions_len] = (InputAction) {
|
|
.negative = _keys + SDL_SCANCODE_UNKNOWN,
|
|
.positive = _keys + key,
|
|
.delegate = delegate
|
|
};
|
|
++_actions_len;
|
|
}
|
|
|
|
static
|
|
void _remove_element(InputAction* item) {
|
|
InputAction* next = item + 1;
|
|
|
|
if(next < _actions + _actions_len) {
|
|
memmove(item, next, (_actions + _actions_len) - next);
|
|
}
|
|
|
|
--_actions_len;
|
|
}
|
|
|
|
void input_remove_actions(InputActionDelegate delegate) {
|
|
for(InputAction* action = _actions; action < _actions + _actions_len; ++action) {
|
|
if(action->delegate == delegate) {
|
|
_remove_element(action);
|
|
}
|
|
}
|
|
}
|