fencer/core/src/input.c
2023-11-29 14:14:01 +01:00

106 lines
2.9 KiB
C

#include "input.h"
#include "input_axis.h"
#include "debug.h"
static List _devices;
static inline
void _internal_open_keyboard() {
InputDevice* keyboard = malloc(sizeof(InputDevice));
ASSERT_RETURN(keyboard != NULL, , "Failed to allocate space for keyboard input device");
*keyboard = (InputDevice){
.listeners = NULL,
.type = InputDevice_KBM,
.id = -1,
.keyboard = {
.state = SDL_GetKeyboardState(NULL)
}
};
list_add(&_devices, &keyboard);
LOG_INFO("registered keyboard %d", keyboard->id);
}
static inline
void _internal_open_controller(int id) {
InputDevice* device = malloc(sizeof(InputDevice));
ASSERT_RETURN(device != NULL, , "Failed to allocate space for gamecontroller input device");
*device = (InputDevice) {
.listeners = NULL,
.type = InputDevice_Gamepad,
.id = id,
.gamepad = {
.id = id,
.controller = SDL_GameControllerOpen(id)
}
};
list_add(&_devices, &device);
LOG_INFO("registered game controller %d", device->id);
}
void input_init() {
_devices = list_from_type(InputDevice*);
// open the keyboard by default
_internal_open_keyboard();
// open any controllers already available
const int joystick_count = SDL_NumJoysticks();
for(int i = 0; i < joystick_count; ++i) {
_internal_open_controller(i);
}
}
void input_clean() {
list_foreach(InputDevice**, _device, &_devices) {
InputDevice* device = *_device;
if(device->type == InputDevice_Gamepad)
SDL_GameControllerClose(device->gamepad.controller);
free(device);
}
list_empty(&_devices);
}
void input_handle_event(SDL_Event event) {
list_foreach(InputDevice**, _device, &_devices) {
InputDevice* device = *_device;
if(device->listeners != NULL) {
list_foreach(InputListener*, listener, device->listeners) {
InputAxis axis = listener->axis;
if(axis.tc->is_changed_by(axis.data, event)) {
InputEvent value = axis.tc->evaluate(axis.data, event);
listener->fn(listener->self, value);
}
}
}
}
}
void input_device_set_listeners(InputDevice* self, List* listeners) {
if(self->listeners != NULL) {
list_foreach(InputListener*, listener, self->listeners) {
listener->axis.tc->set_device(listener->axis.data, NULL);
}
}
self->listeners = listeners;
if(listeners == NULL)
return;
list_foreach(InputListener*, listener, listeners)
listener->axis.tc->set_device(listener->axis.data, self);
LOG_INFO("Set listeners for device %d to %p", self->id, listeners);
}
InputDevice* input_get_device_by_id(int id) {
list_foreach(InputDevice**, _device, &_devices) {
InputDevice* device = *_device;
if(device->id == id) {
return device;
}
}
return NULL;
}