mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-08-14 14:25:19 +00:00
Improve tap responsiveness in GL touch joystick
This commit is contained in:
@@ -350,7 +350,7 @@ public enum Apple2Preferences {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int intValue(Apple2Activity activity) {
|
public int intValue(Apple2Activity activity) {
|
||||||
int defaultLatency = 3; // /TAPDELAY_NUM_CHOICES * TAPDELAY_SCALE -> 0.075f
|
int defaultLatency = 8; // /TAPDELAY_NUM_CHOICES * TAPDELAY_SCALE -> 0.2f
|
||||||
return activity.getPreferences(Context.MODE_PRIVATE).getInt(toString(), defaultLatency);
|
return activity.getPreferences(Context.MODE_PRIVATE).getInt(toString(), defaultLatency);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -26,6 +26,7 @@ static struct {
|
|||||||
void (*buttonDrawCallback)(char newChar);
|
void (*buttonDrawCallback)(char newChar);
|
||||||
|
|
||||||
bool trackingButton;
|
bool trackingButton;
|
||||||
|
bool trackingButtonMove;
|
||||||
pthread_t tapDelayThreadId;
|
pthread_t tapDelayThreadId;
|
||||||
pthread_mutex_t tapDelayMutex;
|
pthread_mutex_t tapDelayMutex;
|
||||||
pthread_cond_t tapDelayCond;
|
pthread_cond_t tapDelayCond;
|
||||||
@@ -71,54 +72,61 @@ static void *_button_tap_delayed_thread(void *dummyptr) {
|
|||||||
|
|
||||||
pthread_mutex_lock(&joys.tapDelayMutex);
|
pthread_mutex_lock(&joys.tapDelayMutex);
|
||||||
|
|
||||||
do {
|
bool deepSleep = false;
|
||||||
pthread_cond_wait(&joys.tapDelayCond, &joys.tapDelayMutex);
|
uint8_t currJoyButtonValue0 = 0x0;
|
||||||
TOUCH_JOY_LOG(">>> [DELAYEDTAP] begin ...");
|
uint8_t currJoyButtonValue1 = 0x0;
|
||||||
|
uint8_t currButtonDisplayChar = ' ';
|
||||||
|
for (;;) {
|
||||||
if (UNLIKELY(joyglobals.isShuttingDown)) {
|
if (UNLIKELY(joyglobals.isShuttingDown)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timespec ts = { .tv_sec=0, .tv_nsec=joys.tapDelayNanos };
|
struct timespec wait;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &wait); // should use CLOCK_MONOTONIC ?
|
||||||
|
wait = timespec_add(wait, joys.tapDelayNanos);
|
||||||
|
int timedOut = pthread_cond_timedwait(&joys.tapDelayCond, &joys.tapDelayMutex, &wait); // wait and possibly consume event
|
||||||
|
assert((!timedOut || timedOut == ETIMEDOUT) && "should not fail any other way");
|
||||||
|
|
||||||
// sleep for the configured delay time
|
if (!timedOut) {
|
||||||
pthread_mutex_unlock(&joys.tapDelayMutex);
|
if (!deepSleep) {
|
||||||
nanosleep(&ts, NULL);
|
if (joys.trackingButtonMove) {
|
||||||
pthread_mutex_lock(&joys.tapDelayMutex);
|
// dragging
|
||||||
|
currJoyButtonValue0 = 0x0;
|
||||||
// wait until touch up/cancel
|
currJoyButtonValue1 = 0x0;
|
||||||
do {
|
currButtonDisplayChar = joys.currButtonDisplayChar;
|
||||||
|
} else if (joys.trackingButton) {
|
||||||
// now set the joystick button values
|
// touch down -- delay consumption to determine if tap or drag
|
||||||
joy_button0 = joys.currJoyButtonValue0;
|
currJoyButtonValue0 = joys.currJoyButtonValue0;
|
||||||
joy_button1 = joys.currJoyButtonValue1;
|
currJoyButtonValue1 = joys.currJoyButtonValue1;
|
||||||
joys.buttonDrawCallback(joys.currButtonDisplayChar);
|
currButtonDisplayChar = joys.currButtonDisplayChar;
|
||||||
|
joys.buttonDrawCallback(currButtonDisplayChar);
|
||||||
if (!joys.trackingButton || joyglobals.isShuttingDown) {
|
// zero the buttons before delay
|
||||||
break;
|
_reset_buttons_state();
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// touch up becomes tap
|
||||||
|
joys.currJoyButtonValue0 = currJoyButtonValue0;
|
||||||
|
joys.currJoyButtonValue1 = currJoyButtonValue1;
|
||||||
|
joys.currButtonDisplayChar = currButtonDisplayChar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
joy_button0 = joys.currJoyButtonValue0;
|
||||||
pthread_mutex_unlock(&joys.tapDelayMutex);
|
joy_button1 = joys.currJoyButtonValue1;
|
||||||
nanosleep(&ts, NULL);
|
joys.buttonDrawCallback(joys.currButtonDisplayChar);
|
||||||
pthread_mutex_lock(&joys.tapDelayMutex);
|
|
||||||
|
|
||||||
_reset_buttons_state();
|
deepSleep = false;
|
||||||
|
if (timedOut && !joys.trackingButton) {
|
||||||
TOUCH_JOY_LOG(">>> [DELAYEDTAP] end ...");
|
deepSleep = true;
|
||||||
} while (1);
|
_reset_buttons_state();
|
||||||
|
TOUCH_JOY_LOG(">>> [DELAYEDTAP] end ...");
|
||||||
|
pthread_cond_wait(&joys.tapDelayCond, &joys.tapDelayMutex); // consume initial touch down
|
||||||
|
TOUCH_JOY_LOG(">>> [DELAYEDTAP] begin ...");
|
||||||
|
} else {
|
||||||
|
TOUCH_JOY_LOG(">>> [DELAYEDTAP] event looping ...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&joys.tapDelayMutex);
|
pthread_mutex_unlock(&joys.tapDelayMutex);
|
||||||
|
|
||||||
@@ -183,7 +191,7 @@ static void touchjoy_axisUp(int x, int y) {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// button state
|
// button state
|
||||||
|
|
||||||
static void _set_current_button_state(touchjoy_button_type_t theButtonChar, int theButtonScancode) {
|
static void _set_current_button_state(touchjoy_button_type_t theButtonChar) {
|
||||||
if (theButtonChar == TOUCH_BUTTON0) {
|
if (theButtonChar == TOUCH_BUTTON0) {
|
||||||
joys.currJoyButtonValue0 = 0x80;
|
joys.currJoyButtonValue0 = 0x80;
|
||||||
joys.currJoyButtonValue1 = 0;
|
joys.currJoyButtonValue1 = 0;
|
||||||
@@ -204,30 +212,30 @@ static void _set_current_button_state(touchjoy_button_type_t theButtonChar, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void touchjoy_buttonDown(void) {
|
static void touchjoy_buttonDown(void) {
|
||||||
_set_current_button_state(buttons.touchDownChar, buttons.touchDownScancode);
|
_set_current_button_state(buttons.touchDownChar);
|
||||||
joys.trackingButton = true;
|
joys.trackingButton = true;
|
||||||
_signal_tap_delay();
|
_signal_tap_delay();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void touchjoy_buttonMove(int dx, int dy) {
|
static void touchjoy_buttonMove(int dx, int dy) {
|
||||||
if ((dy < -joyglobals.switchThreshold) || (dy > joyglobals.switchThreshold)) {
|
if ((dy < -joyglobals.switchThreshold) || (dy > joyglobals.switchThreshold)) {
|
||||||
|
|
||||||
touchjoy_button_type_t theButtonChar = -1;
|
touchjoy_button_type_t theButtonChar = -1;
|
||||||
int theButtonScancode = -1;
|
|
||||||
if (dy < 0) {
|
if (dy < 0) {
|
||||||
theButtonChar = buttons.northChar;
|
theButtonChar = buttons.northChar;
|
||||||
theButtonScancode = buttons.northScancode;
|
|
||||||
} else {
|
} else {
|
||||||
theButtonChar = buttons.southChar;
|
theButtonChar = buttons.southChar;
|
||||||
theButtonScancode = buttons.southScancode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_set_current_button_state(theButtonChar, theButtonScancode);
|
_set_current_button_state(theButtonChar);
|
||||||
_signal_tap_delay();
|
_signal_tap_delay();
|
||||||
}
|
}
|
||||||
|
joys.trackingButtonMove = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void touchjoy_buttonUp(int dx, int dy) {
|
static void touchjoy_buttonUp(int dx, int dy) {
|
||||||
joys.trackingButton = false;
|
joys.trackingButton = false;
|
||||||
|
joys.trackingButtonMove = false;
|
||||||
_signal_tap_delay();
|
_signal_tap_delay();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +246,12 @@ static void gltouchjoy_setTapDelay(float secs) {
|
|||||||
if (UNLIKELY(secs > 1.f)) {
|
if (UNLIKELY(secs > 1.f)) {
|
||||||
ERRLOG("Clamping tap delay to 1.0 secs");
|
ERRLOG("Clamping tap delay to 1.0 secs");
|
||||||
}
|
}
|
||||||
joys.tapDelayNanos = (unsigned int)((float)NANOSECONDS_PER_SECOND * secs);
|
unsigned int tapDelayNanos = (unsigned int)((float)NANOSECONDS_PER_SECOND * secs);
|
||||||
|
#define MIN_WAIT_NANOS 1000000
|
||||||
|
if (tapDelayNanos < MIN_WAIT_NANOS) {
|
||||||
|
tapDelayNanos = MIN_WAIT_NANOS;
|
||||||
|
}
|
||||||
|
joys.tapDelayNanos = tapDelayNanos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user