191 lines
5.9 KiB
C
191 lines
5.9 KiB
C
#include "input_axis.h"
|
|
#include "debug.h"
|
|
#include "input.h"
|
|
|
|
KeyBind* keybind_new(SDL_Scancode key) {
|
|
KeyBind* self = malloc(sizeof(KeyBind));
|
|
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for KeyBind instance");
|
|
*self = (KeyBind) {
|
|
.device = NULL,
|
|
.scancode = key,
|
|
.state = 0
|
|
};
|
|
return self;
|
|
}
|
|
|
|
int keybind_is_changed_by(KeyBind* self, SDL_Event event) {
|
|
return self->device->type == InputDevice_KBM
|
|
&& (event.type == SDL_KEYUP || event.type == SDL_KEYDOWN)
|
|
&& event.key.keysym.scancode == self->scancode;
|
|
}
|
|
|
|
InputEvent keybind_evaluate(KeyBind* self, SDL_Event event) {
|
|
return (InputEvent) {
|
|
.type = InputEvent_Bool,
|
|
.as_bool = self->device->keyboard.state[self->scancode]
|
|
};
|
|
}
|
|
|
|
void keybind_set_device(KeyBind* self, InputDevice* device) {
|
|
self->device = device;
|
|
}
|
|
|
|
ControllerAxis* controlleraxis_new(int axis) {
|
|
ControllerAxis* self = malloc(sizeof(ControllerAxis));
|
|
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for ControllerAxis instance");
|
|
*self = (ControllerAxis){
|
|
.axis = axis,
|
|
.device = NULL
|
|
};
|
|
return self;
|
|
}
|
|
|
|
int controlleraxis_is_changed_by(ControllerAxis* self, SDL_Event event) {
|
|
int r = self->device->type == InputDevice_Gamepad
|
|
&& event.type == SDL_CONTROLLERAXISMOTION
|
|
&& event.caxis.which == self->device->gamepad.id
|
|
&& event.caxis.axis == self->axis;
|
|
return r;
|
|
}
|
|
|
|
InputEvent controlleraxis_evaluate(ControllerAxis* self, SDL_Event event) {
|
|
float result = (float)event.caxis.value / 32767.0;
|
|
return (InputEvent) {
|
|
.type = InputEvent_Float,
|
|
.as_float = result
|
|
};
|
|
}
|
|
|
|
void controlleraxis_set_device(ControllerAxis* self, InputDevice* device) {
|
|
self->device = device;
|
|
}
|
|
|
|
ControllerButton* controllerbutton_new(int button) {
|
|
ControllerButton* self = malloc(sizeof(ControllerButton));
|
|
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for ControllerButton instance");
|
|
*self = (ControllerButton) {
|
|
.button = button,
|
|
.device = NULL
|
|
};
|
|
return self;
|
|
}
|
|
|
|
int controllerbutton_is_changed_by(ControllerButton* self, SDL_Event event) {
|
|
return self->device->type == InputDevice_Gamepad
|
|
&& event.cbutton.which == self->device->gamepad.id
|
|
&& (event.type == SDL_CONTROLLERBUTTONUP || event.type == SDL_CONTROLLERBUTTONDOWN)
|
|
&& event.cbutton.button == self->button;
|
|
}
|
|
|
|
InputEvent controllerbutton_evaluate(ControllerButton* self, SDL_Event event) {
|
|
return (InputEvent) {
|
|
.type = InputEvent_Bool,
|
|
.as_bool = event.cbutton.state
|
|
};
|
|
}
|
|
|
|
void controllerbutton_set_device(ControllerButton* self, InputDevice* device) {
|
|
self->device = device;
|
|
}
|
|
|
|
CompositeAxis1D* compositeaxis1d_new(InputAxis left, InputAxis right, InputEventType type) {
|
|
CompositeAxis1D* self = malloc(sizeof(CompositeAxis1D));
|
|
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for CompositeAxis1D instance");
|
|
*self = (CompositeAxis1D) {
|
|
.left = left,
|
|
.right = right,
|
|
.type = type,
|
|
};
|
|
return self;
|
|
}
|
|
|
|
int compositeaxis1d_is_changed_by(CompositeAxis1D* self, SDL_Event event) {
|
|
return self->left.tc->is_changed_by(self->left.data, event)
|
|
|| self->right.tc->is_changed_by(self->right.data, event);
|
|
}
|
|
|
|
static inline
|
|
InputEvent _internal_event_to_type(InputEventType type, InputEvent event) {
|
|
if(type == InputEvent_Vector && event.type == InputEvent_Vector)
|
|
return event;
|
|
|
|
float as_float = 0;
|
|
switch(event.type) {
|
|
case InputEvent_Vector:
|
|
LOG_ERROR("No (1)");
|
|
break;
|
|
case InputEvent_Bool:
|
|
as_float = event.as_bool;
|
|
break;
|
|
case InputEvent_Float:
|
|
as_float = event.as_float;
|
|
break;
|
|
case InputEvent_Int:
|
|
as_float = event.as_int;
|
|
break;
|
|
}
|
|
event.type = type;
|
|
switch(type) {
|
|
case InputEvent_Int:
|
|
event.as_int = round(as_float);
|
|
return event;
|
|
case InputEvent_Float:
|
|
event.as_float = as_float;
|
|
return event;
|
|
case InputEvent_Bool:
|
|
event.as_bool = as_float != 0;
|
|
return event;
|
|
case InputEvent_Vector:
|
|
LOG_ERROR("No (2)");
|
|
return event;
|
|
}
|
|
return event;
|
|
}
|
|
|
|
InputEvent compositeaxis1d_evaluate(CompositeAxis1D* self, SDL_Event event) {
|
|
InputEvent left_result = self->left.tc->evaluate(self->left.data, event);
|
|
InputEvent right_result = self->right.tc->evaluate(self->right.data, event);
|
|
|
|
ASSERT_RETURN(self->type != InputEvent_Vector
|
|
|| (left_result.type == InputEvent_Vector && right_result.type == InputEvent_Vector),
|
|
((InputEvent){.type = 0, .as_bool = 0}), "Composite axis can only output vector if both composite elements output vector.");
|
|
|
|
InputEvent final = {
|
|
.type = self->type
|
|
};
|
|
// if both outputs are booleans, they will be combined to an int
|
|
if(final.type == InputEvent_Bool)
|
|
final.type = InputEvent_Int;
|
|
|
|
left_result = _internal_event_to_type(final.type, left_result);
|
|
right_result = _internal_event_to_type(final.type, right_result);
|
|
|
|
switch(final.type) {
|
|
default:
|
|
LOG_ERROR("Invalid composite input result");
|
|
final.type = InputEvent_Bool;
|
|
final.as_bool = 0;
|
|
return final;
|
|
case InputEvent_Int:
|
|
final.as_int = right_result.as_int - left_result.as_int;
|
|
return final;
|
|
case InputEvent_Float:
|
|
final.as_float = right_result.as_float - left_result.as_float;
|
|
return final;
|
|
case InputEvent_Vector:
|
|
final.as_vector = vsubf(right_result.as_vector, left_result.as_vector);
|
|
return final;
|
|
}
|
|
}
|
|
|
|
void compositeaxis1d_set_device(CompositeAxis1D* self, InputDevice* device) {
|
|
self->left.tc->set_device(self->left.data, device);
|
|
self->right.tc->set_device(self->right.data, device);
|
|
}
|
|
|
|
void compositeaxis1d_drop(CompositeAxis1D* self) {
|
|
self->left.drop->drop(self->left.data);
|
|
self->right.drop->drop(self->right.data);
|
|
free(self);
|
|
}
|