twn_input: singleton rework, twn_control.h and fixes

This commit is contained in:
2024-10-08 10:12:30 +03:00
parent aef3f6444e
commit 0ede612bec
17 changed files with 677 additions and 647 deletions

View File

@ -1,5 +1,6 @@
#include "twn_input_c.h"
#include "twn_util.h"
#include "twn_control.h"
#include "twn_engine_context_c.h"
#include <SDL2/SDL.h>
@ -38,7 +39,7 @@ static void update_action_pressed_state(InputState *input, Action *action) {
action->just_changed = !action->is_pressed;
action->is_pressed = true;
action->position.x = (float)input->mouse_window_position.x;
action->position.x = (float)input->mouse_window_position.x;
action->position.y = (float)input->mouse_window_position.y;
/* TODO: */
/*
@ -63,7 +64,7 @@ static void update_action_pressed_state(InputState *input, Action *action) {
static void input_bind_code_to_action(InputState *input,
char *action_name,
char const *action_name,
ButtonSource source,
union ButtonCode code)
{
@ -120,7 +121,7 @@ static void input_bind_code_to_action(InputState *input,
static void input_unbind_code_from_action(InputState *input,
char *action_name,
char const *action_name,
ButtonSource source,
union ButtonCode code)
{
@ -193,6 +194,9 @@ void input_state_update(InputState *input) {
SDL_GetRelativeMouseState(&input->mouse_relative_position.x,
&input->mouse_relative_position.y);
ctx.game.mouse_window_position = input->mouse_window_position;
ctx.game.mouse_relative_position = input->mouse_relative_position;
for (size_t i = 0; i < shlenu(input->action_hash); ++i) {
Action *action = &input->action_hash[i].value;
update_action_pressed_state(input, action);
@ -200,76 +204,82 @@ void input_state_update(InputState *input) {
}
void input_bind_action_scancode(InputState *input,
char *action_name,
Scancode scancode)
void input_bind_action_control(char const *action_name,
Control control)
{
input_bind_code_to_action(input,
action_name,
BUTTON_SOURCE_KEYBOARD_PHYSICAL,
(union ButtonCode) { .scancode = scancode });
}
SDL_assert_always(action_name);
void input_unbind_action_scancode(InputState *input,
char *action_name,
Scancode scancode)
{
input_unbind_code_from_action(input,
if (CONTROL_SCANCODE_START <= control && control < CONTROL_SCANCODE_LIMIT)
input_bind_code_to_action(&ctx.input,
action_name,
BUTTON_SOURCE_KEYBOARD_PHYSICAL,
(union ButtonCode) { .scancode = scancode });
}
(union ButtonCode) { .scancode = (SDL_Scancode)control });
void input_bind_action_mouse(InputState *input,
char *action_name,
uint8_t mouse_button)
{
input_bind_code_to_action(input,
action_name,
BUTTON_SOURCE_MOUSE,
(union ButtonCode) { .mouse_button = mouse_button});
}
void input_unbind_action_mouse(InputState *input,
char *action_name,
uint8_t mouse_button)
{
input_unbind_code_from_action(input,
else if (CONTROL_MOUSECODE_START <= control && control < CONTROL_MOUSECODE_LIMIT) {
uint8_t const mouse_button = (uint8_t)(control - CONTROL_MOUSECODE_START);
input_bind_code_to_action(&ctx.input,
action_name,
BUTTON_SOURCE_MOUSE,
(union ButtonCode) { .mouse_button = mouse_button});
(union ButtonCode) { .mouse_button = SDL_BUTTON(mouse_button)});
} else
log_warn("(%s) Invalid control value given: %i.", __func__, control);
}
void input_add_action(InputState *input, char *action_name) {
if (shgeti(input->action_hash, action_name) >= 0) {
void input_unbind_action_control(char const *action_name,
Control control)
{
SDL_assert_always(action_name);
if (CONTROL_SCANCODE_START <= control && control < CONTROL_SCANCODE_LIMIT)
input_unbind_code_from_action(&ctx.input,
action_name,
BUTTON_SOURCE_KEYBOARD_PHYSICAL,
(union ButtonCode) { .scancode = (SDL_Scancode)control });
else if (CONTROL_MOUSECODE_START <= control && control < CONTROL_MOUSECODE_LIMIT) {
uint8_t const mouse_button = (uint8_t)(control - CONTROL_MOUSECODE_START);
input_unbind_code_from_action(&ctx.input,
action_name,
BUTTON_SOURCE_MOUSE,
(union ButtonCode) { .mouse_button = SDL_BUTTON(mouse_button)});
} else
log_warn("(%s) Invalid control value given: %i.", __func__, control);
}
void input_add_action(char const *action_name) {
SDL_assert_always(action_name);
if (shgeti(ctx.input.action_hash, action_name) >= 0) {
log_warn("(%s) Action \"%s\" is already registered.", __func__, action_name);
return;
}
Action new_action = { 0 };
new_action.bindings = ccalloc(ctx.keybind_slots, sizeof *new_action.bindings);
shput(input->action_hash, action_name, new_action);
shput(ctx.input.action_hash, action_name, new_action);
}
void input_delete_action(InputState *input, char *action_name) {
ActionHashItem *action = shgetp_null(input->action_hash, action_name);
void input_delete_action(char const *action_name) {
SDL_assert_always(action_name);
ActionHashItem *action = shgetp_null(ctx.input.action_hash, action_name);
if (action == NULL) {
log_warn("(%s) Action \"%s\" is not registered.", __func__, action_name);
return;
}
SDL_free(action->value.bindings);
shdel(input->action_hash, action_name);
shdel(ctx.input.action_hash, action_name);
}
bool input_is_action_pressed(InputState *input, char *action_name) {
ActionHashItem *action = shgetp_null(input->action_hash, action_name);
bool input_is_action_pressed(char const *action_name) {
SDL_assert_always(action_name);
ActionHashItem *action = shgetp_null(ctx.input.action_hash, action_name);
if (action == NULL) {
log_warn("(%s) Action \"%s\" does not exist.", __func__, action_name);
return false;
@ -278,8 +288,10 @@ bool input_is_action_pressed(InputState *input, char *action_name) {
}
bool input_is_action_just_pressed(InputState *input, char *action_name) {
ActionHashItem *action = shgetp_null(input->action_hash, action_name);
bool input_is_action_just_pressed(char const *action_name) {
SDL_assert_always(action_name);
ActionHashItem *action = shgetp_null(ctx.input.action_hash, action_name);
if (action == NULL) {
log_warn("(%s) Action \"%s\" does not exist.", __func__, action_name);
return false;
@ -288,8 +300,10 @@ bool input_is_action_just_pressed(InputState *input, char *action_name) {
}
bool input_is_action_just_released(InputState *input, char *action_name) {
ActionHashItem *action = shgetp_null(input->action_hash, action_name);
bool input_is_action_just_released(char const *action_name) {
SDL_assert_always(action_name);
ActionHashItem *action = shgetp_null(ctx.input.action_hash, action_name);
if (action == NULL) {
log_warn("(%s) Action \"%s\" does not exist.", __func__, action_name);
return false;
@ -298,8 +312,10 @@ bool input_is_action_just_released(InputState *input, char *action_name) {
}
Vec2 input_get_action_position(InputState *input, char *action_name) {
ActionHashItem *action = shgetp_null(input->action_hash, action_name);
Vec2 input_get_action_position(char const *action_name) {
SDL_assert_always(action_name);
ActionHashItem *action = shgetp_null(ctx.input.action_hash, action_name);
if (action == NULL) {
log_warn("(%s) Action \"%s\" does not exist.", __func__, action_name);
return (Vec2) { 0 };
@ -309,15 +325,13 @@ Vec2 input_get_action_position(InputState *input, char *action_name) {
}
void input_set_mouse_captured(InputState *input, bool enabled) {
(void)input;
/* TODO: returns -1 if not supported, but like... do we care? */
SDL_SetRelativeMouseMode(enabled);
void input_set_mouse_captured(bool enabled) {
if (SDL_SetRelativeMouseMode(enabled) != 0)
log_warn("(%s) Mouse capture isn't supported.", __func__);
}
bool input_is_mouse_captured(InputState *input) {
(void)input;
bool input_is_mouse_captured(void) {
return SDL_GetRelativeMouseMode();
}