106 lines
2.9 KiB
C
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;
|
|
}
|