File syn_joystick.c¶
File List > input > syn_joystick.c
Go to the documentation of this file
#include "syn_joystick.h"
#include "../util/syn_assert.h"
#include <math.h>
#include <string.h>
SYN_Status syn_joystick_init(SYN_Joystick *joy, uint16_t center_x, uint16_t center_y,
uint16_t adc_max, uint16_t deadband)
{
SYN_ASSERT(joy != NULL);
SYN_ASSERT(adc_max > 0);
memset(joy, 0, sizeof(*joy));
joy->center_x = center_x;
joy->center_y = center_y;
joy->adc_max = adc_max;
joy->deadband = deadband;
joy->dir = SYN_JOYSTICK_DIR_CENTER;
return SYN_OK;
}
void syn_joystick_feed_adc(SYN_Joystick *joy, uint16_t raw_x, uint16_t raw_y, bool btn)
{
if (joy == NULL)
return;
joy->button_pressed = btn;
int32_t dx = (int32_t)raw_x - (int32_t)joy->center_x;
int32_t dy = (int32_t)raw_y - (int32_t)joy->center_y;
/* Apply deadband filtering */
if (dx > -((int32_t)joy->deadband) && dx < (int32_t)joy->deadband)
dx = 0;
if (dy > -((int32_t)joy->deadband) && dy < (int32_t)joy->deadband)
dy = 0;
/* Calculate percentage (-100 to +100) */
int32_t range_x = (dx >= 0) ? (int32_t)(joy->adc_max - joy->center_x) : (int32_t)joy->center_x;
int32_t range_y = (dy >= 0) ? (int32_t)(joy->adc_max - joy->center_y) : (int32_t)joy->center_y;
if (range_x > 0) {
joy->current_x_pct = (int16_t)((dx * 100) / range_x);
} else {
joy->current_x_pct = 0;
}
if (range_y > 0) {
joy->current_y_pct = (int16_t)((dy * 100) / range_y);
} else {
joy->current_y_pct = 0;
}
/* Clamp percentages */
if (joy->current_x_pct > 100)
joy->current_x_pct = 100;
if (joy->current_x_pct < -100)
joy->current_x_pct = -100;
if (joy->current_y_pct > 100)
joy->current_y_pct = 100;
if (joy->current_y_pct < -100)
joy->current_y_pct = -100;
/* Decode 8-way directional state */
int16_t x = joy->current_x_pct;
int16_t y = joy->current_y_pct;
if (x == 0 && y == 0) {
joy->dir = SYN_JOYSTICK_DIR_CENTER;
} else if (y > 30 && x > 30) {
joy->dir = SYN_JOYSTICK_DIR_UP_RIGHT;
} else if (y > 30 && x < -30) {
joy->dir = SYN_JOYSTICK_DIR_UP_LEFT;
} else if (y < -30 && x > 30) {
joy->dir = SYN_JOYSTICK_DIR_DOWN_RIGHT;
} else if (y < -30 && x < -30) {
joy->dir = SYN_JOYSTICK_DIR_DOWN_LEFT;
} else if (y > 50) {
joy->dir = SYN_JOYSTICK_DIR_UP;
} else if (y < -50) {
joy->dir = SYN_JOYSTICK_DIR_DOWN;
} else if (x > 50) {
joy->dir = SYN_JOYSTICK_DIR_RIGHT;
} else if (x < -50) {
joy->dir = SYN_JOYSTICK_DIR_LEFT;
} else {
joy->dir = SYN_JOYSTICK_DIR_CENTER;
}
}
int16_t syn_joystick_get_x_pct(const SYN_Joystick *joy)
{
if (joy == NULL)
return 0;
return joy->current_x_pct;
}
int16_t syn_joystick_get_y_pct(const SYN_Joystick *joy)
{
if (joy == NULL)
return 0;
return joy->current_y_pct;
}
SYN_JoystickDir syn_joystick_get_dir(const SYN_Joystick *joy)
{
if (joy == NULL)
return SYN_JOYSTICK_DIR_CENTER;
return joy->dir;
}