#include "input.h" #include "input_axis.h" #include "debug.h" static List _devices; static inline void _internal_open_keyboard() { InputDevice* keyboard = malloc(sizeof(InputDevice)); *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(size_t id) { InputDevice* device = malloc(sizeof(InputDevice)); *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 size_t joystick_count = SDL_NumJoysticks(); for(size_t 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; }