input listeners now take object arguments
This commit is contained in:
parent
c4438c86de
commit
78e4558786
|
@ -17,7 +17,7 @@ static Player* player = NULL;
|
||||||
static Level* level = NULL;
|
static Level* level = NULL;
|
||||||
|
|
||||||
static
|
static
|
||||||
void toggle_info_key(int down) {
|
void toggle_info_key(void* null, int down) {
|
||||||
if(down) {
|
if(down) {
|
||||||
g_debug_log_lvl = (g_debug_log_lvl + 1) % 4;
|
g_debug_log_lvl = (g_debug_log_lvl + 1) % 4;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ void toggle_info_key(int down) {
|
||||||
|
|
||||||
static
|
static
|
||||||
void play() {
|
void play() {
|
||||||
input_add_key_action(SDL_SCANCODE_F1, &toggle_info_key);
|
input_add_key_action(NULL, InputDelegate(toggle_info_key), SDL_SCANCODE_F1);
|
||||||
g_camera.fov = 40;
|
g_camera.fov = 40;
|
||||||
|
|
||||||
player = player_new();
|
player = player_new();
|
||||||
|
|
82
src/input.c
82
src/input.c
|
@ -1,46 +1,38 @@
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "list.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct InputAction {
|
typedef struct InputAction {
|
||||||
const uint8_t* positive;
|
const uint8_t* positive;
|
||||||
const uint8_t* negative;
|
const uint8_t* negative;
|
||||||
int last;
|
int last;
|
||||||
|
void* object_arg;
|
||||||
InputActionDelegate delegate;
|
InputActionDelegate delegate;
|
||||||
} InputAction;
|
} InputAction;
|
||||||
|
|
||||||
static InputAction* _actions = NULL;
|
static List _actions;
|
||||||
static size_t _actions_len = 0;
|
|
||||||
static size_t _actions_cap = 0;
|
|
||||||
|
|
||||||
static const uint8_t* _keys;
|
static const uint8_t* _keys;
|
||||||
|
|
||||||
void input_init() {
|
void input_init() {
|
||||||
_actions = malloc(8 * sizeof(InputAction));
|
_actions = list_from_type(InputAction);
|
||||||
if(_actions == NULL) {
|
|
||||||
LOG_ERROR("Failed to allocate memory for input actions array");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_actions_cap = 8;
|
|
||||||
|
|
||||||
_keys = SDL_GetKeyboardState(NULL);
|
_keys = SDL_GetKeyboardState(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void input_clean() {
|
void input_clean() {
|
||||||
free(_actions);
|
list_empty(&_actions);
|
||||||
_actions_len = 0;
|
|
||||||
_actions_cap = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void _key_changed_event(SDL_Event evt) {
|
void _key_changed_event(SDL_Event evt) {
|
||||||
const uint8_t* keyptr = _keys + evt.key.keysym.scancode;
|
const uint8_t* keyptr = _keys + evt.key.keysym.scancode;
|
||||||
for(InputAction* action = _actions; action < _actions + _actions_len; ++action) {
|
list_foreach(InputAction, action, &_actions) {
|
||||||
if(keyptr == action->positive || keyptr == action->negative) {
|
if(keyptr == action->positive || keyptr == action->negative) {
|
||||||
int val = *action->positive - *action->negative;
|
int val = *action->positive - *action->negative;
|
||||||
if(val != action->last) {
|
if(val != action->last) {
|
||||||
action->last = val;
|
action->last = val;
|
||||||
action->delegate(val);
|
action->delegate(action->object_arg, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,60 +48,28 @@ void input_handle_event(SDL_Event event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
void input_add_axis_action(void* object, InputActionDelegate delegate, SDL_Scancode negative, SDL_Scancode positive) {
|
||||||
void _resize_actions_if_needed(size_t needed_amount) {
|
list_add(&_actions, &(InputAction){
|
||||||
if(_actions_cap > needed_amount)
|
|
||||||
return;
|
|
||||||
|
|
||||||
size_t next_amount = _actions_cap;
|
|
||||||
while(next_amount <= needed_amount) {
|
|
||||||
next_amount *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
InputAction* new = realloc(_actions, next_amount);
|
|
||||||
if(new == NULL) {
|
|
||||||
LOG_ERROR("Failed to allocate enough space for adding a new input actions");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_actions = new;
|
|
||||||
_actions_cap = next_amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void input_add_axis_action(SDL_Scancode negative, SDL_Scancode positive, InputActionDelegate delegate) {
|
|
||||||
_resize_actions_if_needed(_actions_len + 1);
|
|
||||||
_actions[_actions_len] = (InputAction){
|
|
||||||
.negative = _keys + negative,
|
.negative = _keys + negative,
|
||||||
.positive = _keys + positive,
|
.positive = _keys + positive,
|
||||||
.delegate = delegate
|
.delegate = delegate,
|
||||||
};
|
.object_arg = object,
|
||||||
++_actions_len;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void input_add_key_action(SDL_Scancode key, InputActionDelegate delegate) {
|
void input_add_key_action(void* object, InputActionDelegate delegate, SDL_Scancode key) {
|
||||||
_resize_actions_if_needed(_actions_len + 1);
|
list_add(&_actions, &(InputAction) {
|
||||||
_actions[_actions_len] = (InputAction) {
|
|
||||||
.negative = _keys + SDL_SCANCODE_UNKNOWN,
|
.negative = _keys + SDL_SCANCODE_UNKNOWN,
|
||||||
.positive = _keys + key,
|
.positive = _keys + key,
|
||||||
.delegate = delegate
|
.delegate = delegate,
|
||||||
};
|
.object_arg = object,
|
||||||
++_actions_len;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
void input_remove_actions(void* object) {
|
||||||
void _remove_element(InputAction* item) {
|
for(size_t i = 0; i < _actions.len; ++i) {
|
||||||
InputAction* next = item + 1;
|
if(list_at_as(InputAction, &_actions, i)->object_arg == object) {
|
||||||
|
list_erase(&_actions, i);
|
||||||
if(next < _actions + _actions_len) {
|
|
||||||
memmove(item, next, (_actions + _actions_len) - next);
|
|
||||||
}
|
|
||||||
|
|
||||||
--_actions_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void input_remove_actions(InputActionDelegate delegate) {
|
|
||||||
for(InputAction* action = _actions; action < _actions + _actions_len; ++action) {
|
|
||||||
if(action->delegate == delegate) {
|
|
||||||
_remove_element(action);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/input.h
16
src/input.h
|
@ -5,15 +5,23 @@
|
||||||
#include <SDL2/SDL_scancode.h>
|
#include <SDL2/SDL_scancode.h>
|
||||||
#include <SDL2/SDL_keyboard.h>
|
#include <SDL2/SDL_keyboard.h>
|
||||||
|
|
||||||
typedef void (*InputActionDelegate)(int value);
|
// input listener
|
||||||
|
typedef void (*InputActionDelegate)(void* object, int value);
|
||||||
|
|
||||||
extern void input_init();
|
extern void input_init();
|
||||||
extern void input_clean();
|
extern void input_clean();
|
||||||
|
|
||||||
|
// handle an input event
|
||||||
extern void input_handle_event(SDL_Event event);
|
extern void input_handle_event(SDL_Event event);
|
||||||
|
|
||||||
extern void input_add_axis_action(SDL_Scancode negative, SDL_Scancode positive, InputActionDelegate delegate);
|
// create a new axis action triggering on a change of either 'negative' or 'positive' and invoking 'delegate' with first argument 'object'
|
||||||
extern void input_add_key_action(SDL_Scancode key, InputActionDelegate delegate);
|
extern void input_add_axis_action(void* object, InputActionDelegate delegate, SDL_Scancode negative, SDL_Scancode positive);
|
||||||
extern void input_remove_actions(InputActionDelegate delegate);
|
// create a new key action triggering on 'key' change invoking 'delegate' on 'object'.
|
||||||
|
extern void input_add_key_action(void* object, InputActionDelegate delegate, SDL_Scancode key);
|
||||||
|
// remove all actions related to 'object'.
|
||||||
|
extern void input_remove_actions(void* object);
|
||||||
|
|
||||||
|
#define InputDelegate(__Listener)\
|
||||||
|
((InputActionDelegate)&__Listener)
|
||||||
|
|
||||||
#endif // !_fencer_input_h
|
#endif // !_fencer_input_h
|
||||||
|
|
24
src/player.c
24
src/player.c
|
@ -8,23 +8,18 @@
|
||||||
#include "physics_world.h"
|
#include "physics_world.h"
|
||||||
#include "game_world.h"
|
#include "game_world.h"
|
||||||
|
|
||||||
static Vector _directional = ZeroVector;
|
|
||||||
static Spritesheet* spr_player_standing = NULL;
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void player_input_h(int val) {
|
void player_input_h(Player* self, int val) {
|
||||||
_directional.x = val * 10.f;
|
self->directional.x = val * 10.f;
|
||||||
}
|
}
|
||||||
static
|
static
|
||||||
void player_input_v(int val) {
|
void player_input_v(Player* self, int val) {
|
||||||
_directional.y = -val * 10.f;
|
self->directional.y = -val * 10.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player* player_new() {
|
Player* player_new() {
|
||||||
input_add_axis_action(SDL_SCANCODE_A, SDL_SCANCODE_D, &player_input_h);
|
|
||||||
input_add_axis_action(SDL_SCANCODE_S, SDL_SCANCODE_W, &player_input_v);
|
|
||||||
|
|
||||||
spr_player_standing = spritesheet_load("assets/sprites/player.png", (IVector){128, 128});
|
Spritesheet* spr_player_standing = spritesheet_load("assets/sprites/player.png", (IVector){128, 128});
|
||||||
|
|
||||||
float ex_w = 0.1f;
|
float ex_w = 0.1f;
|
||||||
float h = .75f;
|
float h = .75f;
|
||||||
|
@ -45,6 +40,8 @@ Player* player_new() {
|
||||||
rigidbody_set_mass(self->rigidbody, 10.f);
|
rigidbody_set_mass(self->rigidbody, 10.f);
|
||||||
physics_world_add_entity(Player_as_PhysicsEntity(self));
|
physics_world_add_entity(Player_as_PhysicsEntity(self));
|
||||||
sprite_set_origin(self->sprite, (Vector){0.25f, 1.f});
|
sprite_set_origin(self->sprite, (Vector){0.25f, 1.f});
|
||||||
|
input_add_axis_action(self, InputDelegate(player_input_h), SDL_SCANCODE_A, SDL_SCANCODE_D);
|
||||||
|
input_add_axis_action(self, InputDelegate(player_input_v), SDL_SCANCODE_S, SDL_SCANCODE_W);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,9 +58,9 @@ void player_start(Player* self) {}
|
||||||
|
|
||||||
void player_update(Player* self, float dt) {
|
void player_update(Player* self, float dt) {
|
||||||
Vector velocity = rigidbody_get_velocity(self->rigidbody);
|
Vector velocity = rigidbody_get_velocity(self->rigidbody);
|
||||||
Vector velocity_target = {self->is_grounded ? _directional.x : velocity.x, velocity.y};
|
Vector velocity_target = {self->is_grounded ? self->directional.x : velocity.x, velocity.y};
|
||||||
if(_directional.y < 0 && self->is_grounded) {
|
if(self->directional.y < 0 && self->is_grounded) {
|
||||||
_directional.y = 0;
|
self->directional.y = 0;
|
||||||
velocity.y = -30.f;
|
velocity.y = -30.f;
|
||||||
rigidbody_set_velocity(self->rigidbody, velocity);
|
rigidbody_set_velocity(self->rigidbody, velocity);
|
||||||
}
|
}
|
||||||
|
@ -80,6 +77,7 @@ void player_free(Player* self) {
|
||||||
rigidbody_destroy(self->rigidbody);
|
rigidbody_destroy(self->rigidbody);
|
||||||
shape_destroy(self->shape);
|
shape_destroy(self->shape);
|
||||||
sprite_destroy(self->sprite);
|
sprite_destroy(self->sprite);
|
||||||
|
input_remove_actions(self);
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ typedef struct Player {
|
||||||
RigidBody* rigidbody;
|
RigidBody* rigidbody;
|
||||||
Shape* shape;
|
Shape* shape;
|
||||||
|
|
||||||
|
Vector directional;
|
||||||
|
|
||||||
Sprite* sprite;
|
Sprite* sprite;
|
||||||
int is_grounded;
|
int is_grounded;
|
||||||
} Player;
|
} Player;
|
||||||
|
|
Loading…
Reference in a new issue