fencer/core/src/input_axis.h
Sara aca01507ed feat: added compositeaxis1d_from_keys and from_buttons
This required moving InputDelegateFn from input.h to input_axis.h
2024-01-12 12:26:23 +01:00

117 lines
3.9 KiB
C

#ifndef _fencer_input_axis_h
#define _fencer_input_axis_h
#include "typeclass_helpers.h"
#include "vmath.h"
#include "drop.h"
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_keyboard.h>
#include <SDL2/SDL_gamecontroller.h>
struct InputDevice;
typedef enum InputEventType {
InputEvent_Vector = 0,
InputEvent_Float = 1,
InputEvent_Int = 2,
InputEvent_Bool = 3,
} InputEventType;
typedef struct InputEvent {
InputEventType type;
union {
Vector as_vector;
float as_float;
int as_int;
int as_bool;
};
} InputEvent;
typedef struct {
int (*const is_changed_by)(void*, SDL_Event);
struct InputEvent (*const evaluate)(void*, SDL_Event);
void (*const set_device)(void*, struct InputDevice*);
} IInputAxis;
typedef struct {
void* data;
IInputAxis const* tc;
IDrop const* drop;
} InputAxis;
typedef void (*InputDelegateFn)(void* self, InputEvent event);
#define impl_InputAxis_for(T, is_changed_by_f, evaluate_f, set_device_f)\
InputAxis T##_as_InputAxis(T* x) {\
TC_FN_TYPECHECK(int, is_changed_by_f, T*, SDL_Event);\
TC_FN_TYPECHECK(struct InputEvent, evaluate_f, T*, SDL_Event);\
TC_FN_TYPECHECK(void, set_device_f, T*, struct InputDevice*);\
static IInputAxis const tc = {\
.is_changed_by = (int(*const)(void*,SDL_Event)) is_changed_by_f,\
.evaluate = (struct InputEvent(*const)(void*,SDL_Event)) evaluate_f,\
.set_device = (void(*const)(void*,struct InputDevice*)) set_device_f\
};\
IDrop const* drop = T##_as_Drop(x).tc;\
return (InputAxis){.data=x, .tc=&tc, .drop = drop};\
}
typedef struct KeyBind {
int state;
SDL_Scancode scancode;
struct InputDevice* device;
} KeyBind;
extern KeyBind* keybind_new(SDL_Scancode bind);
extern int keybind_is_changed_by(KeyBind* self, SDL_Event event);
extern struct InputEvent keybind_evaluate(KeyBind* self, SDL_Event);
extern void keybind_set_device(KeyBind* self, struct InputDevice* device);
decl_typeclass_impl(InputAxis, KeyBind)
decl_typeclass_impl(Drop, KeyBind)
typedef struct ControllerAxis {
struct InputDevice* device;
int axis;
} ControllerAxis;
extern ControllerAxis* controlleraxis_new(int axis);
extern int controlleraxis_is_changed_by(ControllerAxis* self, SDL_Event event);
extern struct InputEvent controlleraxis_evaluate(ControllerAxis* self, SDL_Event event);
extern void controlleraxis_set_device(ControllerAxis* self, struct InputDevice* device);
decl_typeclass_impl(InputAxis, ControllerAxis)
decl_typeclass_impl(Drop, ControllerAxis)
typedef struct ControllerButton {
struct InputDevice* device;
int button;
} ControllerButton;
extern ControllerButton* controllerbutton_new(int button);
extern int controllerbutton_is_changed_by(ControllerButton* self, SDL_Event event);
extern struct InputEvent controllerbutton_evaluate(ControllerButton* self, SDL_Event event);
extern void controllerbutton_set_device(ControllerButton* self, struct InputDevice* device);
decl_typeclass_impl(InputAxis, ControllerButton)
decl_typeclass_impl(Drop, ControllerButton)
typedef struct CompositeAxis1D {
InputAxis left;
InputAxis right;
InputEventType type;
} CompositeAxis1D;
extern CompositeAxis1D* compositeaxis1d_new(InputAxis left, InputAxis right, InputEventType type);
extern int compositeaxis1d_is_changed_by(CompositeAxis1D* self, SDL_Event event);
extern struct InputEvent compositeaxis1d_evaluate(CompositeAxis1D* self, SDL_Event event);
extern void compositeaxis1d_set_device(CompositeAxis1D* self, struct InputDevice* device);
extern void compositeaxis1d_drop(CompositeAxis1D* self);
extern CompositeAxis1D* compositeaxis1d_from_keys(SDL_Scancode negative, SDL_Scancode positive);
extern CompositeAxis1D* compositeaxis1d_from_buttons(int negative, int positive);
decl_typeclass_impl(InputAxis, CompositeAxis1D)
decl_typeclass_impl(Drop, CompositeAxis1D)
#endif // !_fencer_input_axis_h