fencer/core/src/input_axis.h
2023-11-20 12:04:55 +01:00

130 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;
#define impl_InputAxis_for(T, is_changed_by_f, evaluate_f, set_device_f)\
static inline 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);
impl_default_Drop_for(KeyBind)
impl_InputAxis_for(KeyBind,
keybind_is_changed_by,
keybind_evaluate,
keybind_set_device
)
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);
impl_default_Drop_for(ControllerAxis)
impl_InputAxis_for(ControllerAxis,
controlleraxis_is_changed_by,
controlleraxis_evaluate,
controlleraxis_set_device
)
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);
impl_default_Drop_for(ControllerButton)
impl_InputAxis_for(ControllerButton,
controllerbutton_is_changed_by,
controllerbutton_evaluate,
controllerbutton_set_device
)
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);
impl_Drop_for(CompositeAxis1D,
compositeaxis1d_drop
)
impl_InputAxis_for(CompositeAxis1D,
compositeaxis1d_is_changed_by,
compositeaxis1d_evaluate,
compositeaxis1d_set_device
)
#endif // !_fencer_input_axis_h