mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-12-28 12:33:04 +00:00
Move tap delay to joystick variant
- Keypad variant already has a key repeat threshold - Improved variant touch lifecycle naming
This commit is contained in:
parent
f046af0bef
commit
287df44133
@ -15,13 +15,6 @@
|
||||
#error this is a touch interface module, possibly you mean to not compile this at all?
|
||||
#endif
|
||||
|
||||
#define DEBUG_TOUCH_JOY 0
|
||||
#if DEBUG_TOUCH_JOY
|
||||
# define TOUCH_JOY_LOG(...) LOG(__VA_ARGS__)
|
||||
#else
|
||||
# define TOUCH_JOY_LOG(...)
|
||||
#endif
|
||||
|
||||
#define MODEL_DEPTH -1/32.f
|
||||
#define TRACKING_NONE (-1)
|
||||
|
||||
@ -48,7 +41,6 @@
|
||||
#define BUTTON_OBJ_HALF_H (BUTTON_OBJ_H/2.f)
|
||||
|
||||
#define BUTTON_SWITCH_THRESHOLD_DEFAULT 22
|
||||
#define BUTTON_TAP_DELAY_NANOS_DEFAULT 50000000
|
||||
|
||||
GLTouchJoyGlobals joyglobals = { 0 };
|
||||
GLTouchJoyAxes axes = { 0 };
|
||||
@ -199,76 +191,6 @@ static inline void _setup_button_object_with_char(char newChar) {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Tap Delay Thread : delays processing of touch-down so that a different joystick button/key can be fired
|
||||
|
||||
static inline void _signal_tap_delay(void) {
|
||||
pthread_mutex_lock(&buttons.tapDelayMutex);
|
||||
pthread_cond_signal(&buttons.tapDelayCond);
|
||||
pthread_mutex_unlock(&buttons.tapDelayMutex);
|
||||
}
|
||||
|
||||
static void *_button_tap_delayed_thread(void *dummyptr) {
|
||||
LOG(">>> [DELAYEDTAP] thread start ...");
|
||||
|
||||
pthread_mutex_lock(&buttons.tapDelayMutex);
|
||||
|
||||
do {
|
||||
pthread_cond_wait(&buttons.tapDelayCond, &buttons.tapDelayMutex);
|
||||
TOUCH_JOY_LOG(">>> [DELAYEDTAP] begin ...");
|
||||
|
||||
if (UNLIKELY(joyglobals.isShuttingDown)) {
|
||||
break;
|
||||
}
|
||||
|
||||
struct timespec ts = { .tv_sec=0, .tv_nsec=buttons.tapDelayNanos };
|
||||
|
||||
// sleep for the configured delay time
|
||||
pthread_mutex_unlock(&buttons.tapDelayMutex);
|
||||
nanosleep(&ts, NULL);
|
||||
pthread_mutex_lock(&buttons.tapDelayMutex);
|
||||
|
||||
// wait until touch up/cancel
|
||||
do {
|
||||
|
||||
// now set the emulator's joystick button values (or keypad value)
|
||||
uint8_t displayChar = variant.curr->buttonPress();
|
||||
_setup_button_object_with_char(displayChar);
|
||||
|
||||
if ( (buttons.trackingIndex == TRACKING_NONE) || joyglobals.isShuttingDown) {
|
||||
break;
|
||||
}
|
||||
|
||||
pthread_cond_wait(&buttons.tapDelayCond, &buttons.tapDelayMutex);
|
||||
|
||||
if ( (buttons.trackingIndex == TRACKING_NONE) || joyglobals.isShuttingDown) {
|
||||
break;
|
||||
}
|
||||
TOUCH_JOY_LOG(">>> [DELAYEDTAP] looping ...");
|
||||
} while (1);
|
||||
|
||||
if (UNLIKELY(joyglobals.isShuttingDown)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// delay the ending of button tap or touch/move event by the configured delay time
|
||||
pthread_mutex_unlock(&buttons.tapDelayMutex);
|
||||
nanosleep(&ts, NULL);
|
||||
pthread_mutex_lock(&buttons.tapDelayMutex);
|
||||
|
||||
variant.curr->buttonRelease();
|
||||
|
||||
TOUCH_JOY_LOG(">>> [DELAYEDTAP] end ...");
|
||||
} while (1);
|
||||
|
||||
pthread_mutex_unlock(&buttons.tapDelayMutex);
|
||||
|
||||
LOG(">>> [DELAYEDTAP] thread exit ...");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static inline void resetState() {
|
||||
LOG("%s", "");
|
||||
axes.trackingIndex = TRACKING_NONE;
|
||||
@ -286,8 +208,6 @@ static void gltouchjoy_setup(void) {
|
||||
mdlDestroyModel(&buttons.model);
|
||||
|
||||
joyglobals.isShuttingDown = false;
|
||||
assert((buttons.tapDelayThreadId == 0) && "setup called multiple times!");
|
||||
pthread_create(&buttons.tapDelayThreadId, NULL, (void *)&_button_tap_delayed_thread, (void *)NULL);
|
||||
|
||||
axes.model = mdlCreateQuad(-1.05, -1.0, AXIS_OBJ_W, AXIS_OBJ_H, MODEL_DEPTH, AXIS_FB_WIDTH, AXIS_FB_HEIGHT, (GLCustom){
|
||||
.create = &_create_touchjoy_hud,
|
||||
@ -319,6 +239,9 @@ static void gltouchjoy_setup(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
variant.joys->setup(&_setup_button_object_with_char);
|
||||
variant.kpad->setup(&_setup_button_object_with_char);
|
||||
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
axes.timingBegin = now;
|
||||
@ -336,15 +259,10 @@ static void gltouchjoy_shutdown(void) {
|
||||
resetState();
|
||||
|
||||
joyglobals.isAvailable = false;
|
||||
|
||||
joyglobals.isShuttingDown = true;
|
||||
pthread_cond_signal(&buttons.tapDelayCond);
|
||||
if (pthread_join(buttons.tapDelayThreadId, NULL)) {
|
||||
ERRLOG("OOPS: pthread_join tap delay thread ...");
|
||||
}
|
||||
buttons.tapDelayThreadId = 0;
|
||||
buttons.tapDelayMutex = (pthread_mutex_t){ 0 };
|
||||
buttons.tapDelayCond = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
|
||||
|
||||
variant.joys->shutdown();
|
||||
variant.kpad->shutdown();
|
||||
|
||||
mdlDestroyModel(&axes.model);
|
||||
mdlDestroyModel(&buttons.model);
|
||||
@ -495,9 +413,6 @@ static inline void _axis_touch_down(int x, int y) {
|
||||
}
|
||||
|
||||
static inline void _button_touch_down(int x, int y) {
|
||||
variant.curr->setCurrButtonValue(buttons.touchDownChar, buttons.touchDownScancode);
|
||||
_signal_tap_delay();
|
||||
|
||||
buttons.centerX = x;
|
||||
buttons.centerY = y;
|
||||
|
||||
@ -505,11 +420,12 @@ static inline void _button_touch_down(int x, int y) {
|
||||
buttons.modelDirty = true;
|
||||
|
||||
TOUCH_JOY_LOG("---TOUCH %sDOWN (buttons index %d) center:(%d,%d) -> buttons(0x%02X,0x%02X)", (action == TOUCH_DOWN ? "" : "POINTER "), buttons.trackingIndex, buttons.centerX, buttons.centerY, joy_button0, joy_button1);
|
||||
variant.curr->buttonDown();
|
||||
}
|
||||
|
||||
static inline void _axis_move(int x, int y) {
|
||||
x = (x - axes.centerX);
|
||||
y = (y - axes.centerY);
|
||||
x -= axes.centerX;
|
||||
y -= axes.centerY;
|
||||
TOUCH_JOY_LOG("---TOUCH MOVE ...tracking axis:%d (%d,%d) -> joy(0x%02X,0x%02X)", axes.trackingIndex, x, y, joy_x, joy_y);
|
||||
variant.curr->axisMove(x, y);
|
||||
}
|
||||
@ -517,21 +433,8 @@ static inline void _axis_move(int x, int y) {
|
||||
static inline void _button_move(int x, int y) {
|
||||
x -= buttons.centerX;
|
||||
y -= buttons.centerY;
|
||||
if ((y < -joyglobals.switchThreshold) || (y > joyglobals.switchThreshold)) {
|
||||
touchjoy_button_type_t theButtonChar = -1;
|
||||
int theButtonScancode = -1;
|
||||
if (y < 0) {
|
||||
theButtonChar = buttons.northChar;
|
||||
theButtonScancode = buttons.northScancode;
|
||||
} else {
|
||||
theButtonChar = buttons.southChar;
|
||||
theButtonScancode = buttons.southScancode;
|
||||
}
|
||||
|
||||
variant.curr->setCurrButtonValue(theButtonChar, theButtonScancode);
|
||||
_signal_tap_delay();
|
||||
TOUCH_JOY_LOG("+++TOUCH MOVE ...tracking button:%d (%d,%d) -> buttons(0x%02X,0x%02X)", buttons.trackingIndex, x, y, joy_button0, joy_button1);
|
||||
}
|
||||
TOUCH_JOY_LOG("+++TOUCH MOVE ...tracking button:%d (%d,%d) -> buttons(0x%02X,0x%02X)", buttons.trackingIndex, x, y, joy_button0, joy_button1);
|
||||
variant.curr->buttonMove(x, y);
|
||||
}
|
||||
|
||||
static inline void _axis_touch_up(int x, int y) {
|
||||
@ -544,8 +447,8 @@ static inline void _axis_touch_up(int x, int y) {
|
||||
TOUCH_JOY_LOG("---TOUCH %sUP (axis went up)%s", (action == TOUCH_UP ? "" : "POINTER "), (resetIndex ? " (reset buttons index!)" : ""));
|
||||
#endif
|
||||
LOG("%s", "");
|
||||
x = (x - axes.centerX);
|
||||
y = (y - axes.centerY);
|
||||
x -= axes.centerX;
|
||||
y -= axes.centerY;
|
||||
if (buttons.trackingIndex > axes.trackingIndex) {
|
||||
LOG("!!! : DECREMENTING buttons.trackingIndex");
|
||||
--buttons.trackingIndex;
|
||||
@ -554,7 +457,7 @@ static inline void _axis_touch_up(int x, int y) {
|
||||
axes.trackingIndex = TRACKING_NONE;
|
||||
}
|
||||
|
||||
static inline void _button_touch_up(void) {
|
||||
static inline void _button_touch_up(int x, int y) {
|
||||
#if DEBUG_TOUCH_JOY
|
||||
bool resetIndex = false;
|
||||
if (axes.trackingIndex > buttons.trackingIndex) {
|
||||
@ -564,12 +467,14 @@ static inline void _button_touch_up(void) {
|
||||
TOUCH_JOY_LOG("---TOUCH %sUP (buttons went up)%s", (action == TOUCH_UP ? "" : "POINTER "), (resetIndex ? " (reset axis index!)" : ""));
|
||||
#endif
|
||||
LOG("%s", "");
|
||||
x -= buttons.centerX;
|
||||
y -= buttons.centerY;
|
||||
if (axes.trackingIndex > buttons.trackingIndex) {
|
||||
LOG("!!! : DECREMENTING axes.trackingIndex");
|
||||
--axes.trackingIndex;
|
||||
}
|
||||
variant.curr->buttonUp(x, y);
|
||||
buttons.trackingIndex = TRACKING_NONE;
|
||||
_signal_tap_delay();
|
||||
}
|
||||
|
||||
|
||||
@ -648,7 +553,9 @@ static int64_t gltouchjoy_onTouchEvent(interface_touch_event_t action, int point
|
||||
int y = (int)y_coords[axes.trackingIndex];
|
||||
_axis_touch_up(x, y);
|
||||
} else if (pointer_idx == buttons.trackingIndex) {
|
||||
_button_touch_up();
|
||||
int x = (int)x_coords[buttons.trackingIndex];
|
||||
int y = (int)y_coords[buttons.trackingIndex];
|
||||
_button_touch_up(x, y);
|
||||
} else {
|
||||
if (pointer_count == 1) {
|
||||
LOG("!!! : RESETTING TOUCH JOYSTICK STATE MACHINE");
|
||||
@ -764,16 +671,6 @@ static void gltouchjoy_setTouchButtonTypes(
|
||||
_setup_button_object_with_char(currButtonDisplayChar);
|
||||
}
|
||||
|
||||
static void gltouchjoy_setTapDelay(float secs) {
|
||||
if (UNLIKELY(secs < 0.f)) {
|
||||
ERRLOG("Clamping tap delay to 0.0 secs");
|
||||
}
|
||||
if (UNLIKELY(secs > 1.f)) {
|
||||
ERRLOG("Clamping tap delay to 1.0 secs");
|
||||
}
|
||||
buttons.tapDelayNanos = (unsigned int)((float)NANOSECONDS_PER_SECOND * secs);
|
||||
}
|
||||
|
||||
static void gltouchjoy_setTouchAxisSensitivity(float multiplier) {
|
||||
axes.multiplier = multiplier;
|
||||
}
|
||||
@ -883,11 +780,6 @@ static void _init_gltouchjoy(void) {
|
||||
|
||||
buttons.activeChar = MOUSETEXT_OPENAPPLE;
|
||||
|
||||
buttons.tapDelayThreadId = 0;
|
||||
buttons.tapDelayMutex = (pthread_mutex_t){ 0 };
|
||||
buttons.tapDelayCond = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
|
||||
buttons.tapDelayNanos = BUTTON_TAP_DELAY_NANOS_DEFAULT;
|
||||
|
||||
joyglobals.isEnabled = true;
|
||||
joyglobals.ownsScreen = true;
|
||||
joyglobals.showControls = true;
|
||||
@ -904,7 +796,6 @@ static void _init_gltouchjoy(void) {
|
||||
joydriver_ownsScreen = &gltouchjoy_ownsScreen;
|
||||
joydriver_setShowControls = &gltouchjoy_setShowControls;
|
||||
joydriver_setTouchButtonTypes = &gltouchjoy_setTouchButtonTypes;
|
||||
joydriver_setTapDelay = &gltouchjoy_setTapDelay;
|
||||
joydriver_setTouchAxisSensitivity = &gltouchjoy_setTouchAxisSensitivity;
|
||||
joydriver_setButtonSwitchThreshold = &gltouchjoy_setButtonSwitchThreshold;
|
||||
joydriver_setTouchVariant = &gltouchjoy_setTouchVariant;
|
||||
|
@ -17,6 +17,13 @@
|
||||
#include "video/glhudmodel.h"
|
||||
#include "video/glnode.h"
|
||||
|
||||
#define DEBUG_TOUCH_JOY 0
|
||||
#if DEBUG_TOUCH_JOY
|
||||
# define TOUCH_JOY_LOG(...) LOG(__VA_ARGS__)
|
||||
#else
|
||||
# define TOUCH_JOY_LOG(...)
|
||||
#endif
|
||||
|
||||
// globals
|
||||
|
||||
typedef struct GLTouchJoyGlobals {
|
||||
@ -75,23 +82,23 @@ typedef struct GLTouchJoyButtons {
|
||||
int trackingIndex;
|
||||
struct timespec timingBegin;
|
||||
|
||||
pthread_t tapDelayThreadId;
|
||||
pthread_mutex_t tapDelayMutex;
|
||||
pthread_cond_t tapDelayCond;
|
||||
unsigned int tapDelayNanos;
|
||||
|
||||
} GLTouchJoyButtons;
|
||||
extern GLTouchJoyButtons buttons;
|
||||
|
||||
typedef struct GLTouchJoyVariant {
|
||||
touchjoy_variant_t (*variant)(void);
|
||||
void (*resetState)(void);
|
||||
void (*setCurrButtonValue)(touchjoy_button_type_t theButtonChar, int theButtonScancode);
|
||||
uint8_t (*buttonPress)(void);
|
||||
void (*buttonRelease)(void);
|
||||
void (*axisDown)(void);
|
||||
void (*axisMove)(int dx, int dy);
|
||||
void (*axisUp)(int dx, int dy);
|
||||
void (*resetState)(void);
|
||||
void (*setup)(void (*buttonDrawCallback)(char newChar));
|
||||
void (*shutdown)(void);
|
||||
|
||||
void (*buttonDown)(void);
|
||||
void (*buttonMove)(int dx, int dy);
|
||||
void (*buttonUp)(int dx, int dy);
|
||||
|
||||
void (*axisDown)(void);
|
||||
void (*axisMove)(int dx, int dy);
|
||||
void (*axisUp)(int dx, int dy);
|
||||
|
||||
} GLTouchJoyVariant;
|
||||
|
||||
// registers a touch joystick variant with manager
|
||||
|
@ -15,14 +15,25 @@
|
||||
#error this is a touch interface module, possibly you mean to not compile this at all?
|
||||
#endif
|
||||
|
||||
#define BUTTON_TAP_DELAY_NANOS_DEFAULT 50000000
|
||||
|
||||
static GLTouchJoyVariant happyHappyJoyJoy = { 0 };
|
||||
|
||||
static struct {
|
||||
uint8_t currJoyButtonValue0;
|
||||
uint8_t currJoyButtonValue1;
|
||||
uint8_t currButtonDisplayChar;
|
||||
void (*buttonDrawCallback)(char newChar);
|
||||
|
||||
bool trackingButton;
|
||||
pthread_t tapDelayThreadId;
|
||||
pthread_mutex_t tapDelayMutex;
|
||||
pthread_cond_t tapDelayCond;
|
||||
unsigned int tapDelayNanos;
|
||||
} joys;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static touchjoy_variant_t touchjoy_variant(void) {
|
||||
return EMULATED_JOYSTICK;
|
||||
}
|
||||
@ -45,6 +56,93 @@ static void touchjoy_resetState(void) {
|
||||
_reset_buttons_state();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Tap Delay Thread : delays processing of touch-down so that a different joystick button can be fired
|
||||
|
||||
static inline void _signal_tap_delay(void) {
|
||||
pthread_mutex_lock(&joys.tapDelayMutex);
|
||||
pthread_cond_signal(&joys.tapDelayCond);
|
||||
pthread_mutex_unlock(&joys.tapDelayMutex);
|
||||
}
|
||||
|
||||
static void *_button_tap_delayed_thread(void *dummyptr) {
|
||||
LOG(">>> [DELAYEDTAP] thread start ...");
|
||||
|
||||
pthread_mutex_lock(&joys.tapDelayMutex);
|
||||
|
||||
do {
|
||||
pthread_cond_wait(&joys.tapDelayCond, &joys.tapDelayMutex);
|
||||
TOUCH_JOY_LOG(">>> [DELAYEDTAP] begin ...");
|
||||
|
||||
if (UNLIKELY(joyglobals.isShuttingDown)) {
|
||||
break;
|
||||
}
|
||||
|
||||
struct timespec ts = { .tv_sec=0, .tv_nsec=joys.tapDelayNanos };
|
||||
|
||||
// sleep for the configured delay time
|
||||
pthread_mutex_unlock(&joys.tapDelayMutex);
|
||||
nanosleep(&ts, NULL);
|
||||
pthread_mutex_lock(&joys.tapDelayMutex);
|
||||
|
||||
// wait until touch up/cancel
|
||||
do {
|
||||
|
||||
// now set the joystick button values
|
||||
joy_button0 = joys.currJoyButtonValue0;
|
||||
joy_button1 = joys.currJoyButtonValue1;
|
||||
joys.buttonDrawCallback(joys.currButtonDisplayChar);
|
||||
|
||||
if (!joys.trackingButton || joyglobals.isShuttingDown) {
|
||||
break;
|
||||
}
|
||||
|
||||
pthread_cond_wait(&joys.tapDelayCond, &joys.tapDelayMutex);
|
||||
|
||||
if (!joys.trackingButton || joyglobals.isShuttingDown) {
|
||||
break;
|
||||
}
|
||||
TOUCH_JOY_LOG(">>> [DELAYEDTAP] looping ...");
|
||||
} while (1);
|
||||
|
||||
if (UNLIKELY(joyglobals.isShuttingDown)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// delay the ending of button tap or touch/move event by the configured delay time
|
||||
pthread_mutex_unlock(&joys.tapDelayMutex);
|
||||
nanosleep(&ts, NULL);
|
||||
pthread_mutex_lock(&joys.tapDelayMutex);
|
||||
|
||||
_reset_buttons_state();
|
||||
|
||||
TOUCH_JOY_LOG(">>> [DELAYEDTAP] end ...");
|
||||
} while (1);
|
||||
|
||||
pthread_mutex_unlock(&joys.tapDelayMutex);
|
||||
|
||||
LOG(">>> [DELAYEDTAP] thread exit ...");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void touchjoy_setup(void (*buttonDrawCallback)(char newChar)) {
|
||||
assert((joys.tapDelayThreadId == 0) && "setup called multiple times!");
|
||||
joys.buttonDrawCallback = buttonDrawCallback;
|
||||
pthread_create(&joys.tapDelayThreadId, NULL, (void *)&_button_tap_delayed_thread, (void *)NULL);
|
||||
}
|
||||
|
||||
static void touchjoy_shutdown(void) {
|
||||
pthread_cond_signal(&joys.tapDelayCond);
|
||||
if (pthread_join(joys.tapDelayThreadId, NULL)) {
|
||||
ERRLOG("OOPS: pthread_join tap delay thread ...");
|
||||
}
|
||||
joys.tapDelayThreadId = 0;
|
||||
joys.tapDelayMutex = (pthread_mutex_t){ 0 };
|
||||
joys.tapDelayCond = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// axis state
|
||||
|
||||
@ -85,7 +183,7 @@ static void touchjoy_axisUp(int x, int y) {
|
||||
// ----------------------------------------------------------------------------
|
||||
// button state
|
||||
|
||||
static void touchjoy_setCurrButtonValue(touchjoy_button_type_t theButtonChar, int theButtonScancode) {
|
||||
static void _set_current_button_state(touchjoy_button_type_t theButtonChar, int theButtonScancode) {
|
||||
if (theButtonChar == TOUCH_BUTTON0) {
|
||||
joys.currJoyButtonValue0 = 0x80;
|
||||
joys.currJoyButtonValue1 = 0;
|
||||
@ -105,14 +203,42 @@ static void touchjoy_setCurrButtonValue(touchjoy_button_type_t theButtonChar, in
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t touchjoy_buttonPress(void) {
|
||||
joy_button0 = joys.currJoyButtonValue0;
|
||||
joy_button1 = joys.currJoyButtonValue1;
|
||||
return joys.currButtonDisplayChar;
|
||||
static void touchjoy_buttonDown(void) {
|
||||
_set_current_button_state(buttons.touchDownChar, buttons.touchDownScancode);
|
||||
joys.trackingButton = true;
|
||||
_signal_tap_delay();
|
||||
}
|
||||
|
||||
static void touchjoy_buttonRelease(void) {
|
||||
_reset_buttons_state();
|
||||
static void touchjoy_buttonMove(int dx, int dy) {
|
||||
if ((dy < -joyglobals.switchThreshold) || (dy > joyglobals.switchThreshold)) {
|
||||
touchjoy_button_type_t theButtonChar = -1;
|
||||
int theButtonScancode = -1;
|
||||
if (dy < 0) {
|
||||
theButtonChar = buttons.northChar;
|
||||
theButtonScancode = buttons.northScancode;
|
||||
} else {
|
||||
theButtonChar = buttons.southChar;
|
||||
theButtonScancode = buttons.southScancode;
|
||||
}
|
||||
|
||||
_set_current_button_state(theButtonChar, theButtonScancode);
|
||||
_signal_tap_delay();
|
||||
}
|
||||
}
|
||||
|
||||
static void touchjoy_buttonUp(int dx, int dy) {
|
||||
joys.trackingButton = false;
|
||||
_signal_tap_delay();
|
||||
}
|
||||
|
||||
static void gltouchjoy_setTapDelay(float secs) {
|
||||
if (UNLIKELY(secs < 0.f)) {
|
||||
ERRLOG("Clamping tap delay to 0.0 secs");
|
||||
}
|
||||
if (UNLIKELY(secs > 1.f)) {
|
||||
ERRLOG("Clamping tap delay to 1.0 secs");
|
||||
}
|
||||
joys.tapDelayNanos = (unsigned int)((float)NANOSECONDS_PER_SECOND * secs);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -123,15 +249,23 @@ static void _init_gltouchjoy_joy(void) {
|
||||
|
||||
happyHappyJoyJoy.variant = &touchjoy_variant,
|
||||
happyHappyJoyJoy.resetState = &touchjoy_resetState,
|
||||
happyHappyJoyJoy.setup = &touchjoy_setup,
|
||||
happyHappyJoyJoy.shutdown = &touchjoy_shutdown,
|
||||
|
||||
happyHappyJoyJoy.setCurrButtonValue = &touchjoy_setCurrButtonValue,
|
||||
happyHappyJoyJoy.buttonPress = &touchjoy_buttonPress,
|
||||
happyHappyJoyJoy.buttonRelease = &touchjoy_buttonRelease,
|
||||
happyHappyJoyJoy.buttonDown = &touchjoy_buttonDown,
|
||||
happyHappyJoyJoy.buttonMove = &touchjoy_buttonMove,
|
||||
happyHappyJoyJoy.buttonUp = &touchjoy_buttonUp,
|
||||
|
||||
happyHappyJoyJoy.axisDown = &touchjoy_axisDown,
|
||||
happyHappyJoyJoy.axisMove = &touchjoy_axisMove,
|
||||
happyHappyJoyJoy.axisUp = &touchjoy_axisUp,
|
||||
|
||||
joys.tapDelayMutex = (pthread_mutex_t){ 0 };
|
||||
joys.tapDelayCond = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
|
||||
joys.tapDelayNanos = BUTTON_TAP_DELAY_NANOS_DEFAULT;
|
||||
|
||||
joydriver_setTapDelay = &gltouchjoy_setTapDelay;
|
||||
|
||||
gltouchjoy_registerVariant(EMULATED_JOYSTICK, &happyHappyJoyJoy);
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ static struct {
|
||||
keypad_octant_t axisCurrentOctant;
|
||||
|
||||
uint8_t currButtonDisplayChar;
|
||||
void (*buttonDrawCallback)(char newChar);
|
||||
|
||||
// index of repeating scancodes to fire
|
||||
keypad_fire_t fireIdx;
|
||||
@ -162,6 +163,10 @@ static void touchkpad_keyboardReadCallback(void) {
|
||||
}
|
||||
}
|
||||
|
||||
if (fired == REPEAT_BUTTON) {
|
||||
kpad.buttonDrawCallback(kpad.currButtonDisplayChar);
|
||||
}
|
||||
|
||||
bool lockedAxis = _callback_sourceTryLock(&kpad.axisLock);
|
||||
if (lockedAxis) {
|
||||
if (fired == REPEAT_AXIS || fired == REPEAT_AXIS_ALT) {
|
||||
@ -227,6 +232,14 @@ static void touchkpad_resetState(void) {
|
||||
c_keys_handle_input(buttons.southScancode, /*pressed:*/false, /*ASCII:*/false);
|
||||
}
|
||||
|
||||
static void touchkpad_setup(void (*buttonDrawCallback)(char newChar)) {
|
||||
kpad.buttonDrawCallback = buttonDrawCallback;
|
||||
}
|
||||
|
||||
static void touchkpad_shutdown(void) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// axis key(s) state
|
||||
|
||||
@ -465,7 +478,7 @@ static void touchkpad_axisUp(int dx, int dy) {
|
||||
// ----------------------------------------------------------------------------
|
||||
// button key state
|
||||
|
||||
static void touchkpad_setCurrButtonValue(touchjoy_button_type_t theButtonChar, int theButtonScancode) {
|
||||
static void _set_current_button_state(touchjoy_button_type_t theButtonChar, int theButtonScancode) {
|
||||
LOG("%s", "");
|
||||
if (theButtonChar >= 0) {
|
||||
kpad.currButtonDisplayChar = theButtonChar;
|
||||
@ -476,23 +489,40 @@ static void touchkpad_setCurrButtonValue(touchjoy_button_type_t theButtonChar, i
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t touchkpad_buttonPress(void) {
|
||||
LOG("%s", "");
|
||||
static void touchkpad_buttonDown(void) {
|
||||
if (!kpad.buttonBegan) {
|
||||
// avoid multiple locks on extra buttonPress()
|
||||
kpad.buttonBegan = true;
|
||||
_touch_sourceBegin(&kpad.buttonLock);
|
||||
}
|
||||
_set_current_button_state(buttons.touchDownChar, buttons.touchDownScancode);
|
||||
if (kpad.scancodes[REPEAT_BUTTON] >= 0) {
|
||||
LOG("->BUTT : %d/'%c'", kpad.scancodes[REPEAT_BUTTON], kpad.currButtonDisplayChar);
|
||||
clock_gettime(CLOCK_MONOTONIC, &kpad.timingBegins[REPEAT_BUTTON]);
|
||||
keydriver_keyboardReadCallback = &touchkpad_keyboardReadCallback;
|
||||
}
|
||||
return kpad.currButtonDisplayChar;
|
||||
}
|
||||
|
||||
static void touchkpad_buttonRelease(void) {
|
||||
static void touchkpad_buttonMove(int dx, int dy) {
|
||||
// Currently this is the same logic as the "regular" joystick variant ... but we could likely be more creative here
|
||||
// in a future revision, like having a full octant of key possibilities ... (for example, playing Bolo with a friend
|
||||
// on the same tablet, one driving, the other shooting and controlling the turret)
|
||||
if ((dy < -joyglobals.switchThreshold) || (dy > joyglobals.switchThreshold)) {
|
||||
touchjoy_button_type_t theButtonChar = -1;
|
||||
int theButtonScancode = -1;
|
||||
if (dy < 0) {
|
||||
theButtonChar = buttons.northChar;
|
||||
theButtonScancode = buttons.northScancode;
|
||||
} else {
|
||||
theButtonChar = buttons.southChar;
|
||||
theButtonScancode = buttons.southScancode;
|
||||
}
|
||||
_set_current_button_state(theButtonChar, theButtonScancode);
|
||||
}
|
||||
}
|
||||
|
||||
static void touchkpad_buttonUp(int dx, int dy) {
|
||||
LOG("%s", "");
|
||||
touchkpad_buttonMove(dx, dy);
|
||||
kpad.timingBegins[REPEAT_BUTTON] = (struct timespec){ 0 };
|
||||
if (kpad.buttonBegan) {
|
||||
kpad.buttonBegan = false;
|
||||
@ -521,10 +551,12 @@ static void _init_gltouchjoy_kpad(void) {
|
||||
|
||||
kpadJoy.variant = &touchkpad_variant,
|
||||
kpadJoy.resetState = &touchkpad_resetState,
|
||||
kpadJoy.setup = &touchkpad_setup,
|
||||
kpadJoy.shutdown = &touchkpad_shutdown,
|
||||
|
||||
kpadJoy.setCurrButtonValue = &touchkpad_setCurrButtonValue,
|
||||
kpadJoy.buttonPress = &touchkpad_buttonPress,
|
||||
kpadJoy.buttonRelease = &touchkpad_buttonRelease,
|
||||
kpadJoy.buttonDown = &touchkpad_buttonDown,
|
||||
kpadJoy.buttonMove = &touchkpad_buttonMove,
|
||||
kpadJoy.buttonUp = &touchkpad_buttonUp,
|
||||
|
||||
kpadJoy.axisDown = &touchkpad_axisDown,
|
||||
kpadJoy.axisMove = &touchkpad_axisMove,
|
||||
|
Loading…
Reference in New Issue
Block a user