diff --git a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2JoystickSettingsMenu.java b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2JoystickSettingsMenu.java
index f5379a51..0607a1c7 100644
--- a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2JoystickSettingsMenu.java
+++ b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2JoystickSettingsMenu.java
@@ -226,6 +226,104 @@ public class Apple2JoystickSettingsMenu extends Apple2AbstractMenu {
});
}
},
+ JOYSTICK_SWIPELEFT_BUTTON {
+ @Override
+ public final String getTitle(Apple2Activity activity) {
+ return activity.getResources().getString(R.string.joystick_button_swipe_left_button);
+ }
+
+ @Override
+ public final String getSummary(Apple2Activity activity) {
+ return activity.getResources().getString(R.string.joystick_button_swipe_left_button_summary);
+ }
+
+ @Override
+ public String getPrefKey() {
+ return "jsSwipeWestChar";
+ }
+
+ @Override
+ public Object getPrefDefault() {
+ return TouchJoystickButtons.NONE.ordinal();
+ }
+
+ @Override
+ public View getView(final Apple2Activity activity, View convertView) {
+ convertView = _basicView(activity, this, convertView);
+ _addPopupIcon(activity, this, convertView);
+ return convertView;
+ }
+
+ @Override
+ public void handleSelection(final Apple2Activity activity, final Apple2AbstractMenu settingsMenu, boolean isChecked) {
+ final IMenuEnum self = this;
+ _alertDialogHandleSelection(activity, R.string.joystick_button_swipe_left_button, new String[]{
+ activity.getResources().getString(R.string.joystick_button_button_none),
+ activity.getResources().getString(R.string.joystick_button_button1),
+ activity.getResources().getString(R.string.joystick_button_button2),
+ activity.getResources().getString(R.string.joystick_button_button_both),
+ }, new IPreferenceLoadSave() {
+ @Override
+ public int intValue() {
+ return (int) Apple2Preferences.getJSONPref(self);
+ }
+
+ @Override
+ public void saveInt(int value) {
+ Apple2Preferences.setJSONPref(self, TouchJoystickButtons.values()[value].ordinal());
+ }
+ });
+ }
+ },
+ JOYSTICK_SWIPERIGHT_BUTTON {
+ @Override
+ public final String getTitle(Apple2Activity activity) {
+ return activity.getResources().getString(R.string.joystick_button_swipe_right_button);
+ }
+
+ @Override
+ public final String getSummary(Apple2Activity activity) {
+ return activity.getResources().getString(R.string.joystick_button_swipe_right_button_summary);
+ }
+
+ @Override
+ public String getPrefKey() {
+ return "jsSwipeEastChar";
+ }
+
+ @Override
+ public Object getPrefDefault() {
+ return TouchJoystickButtons.NONE.ordinal();
+ }
+
+ @Override
+ public View getView(final Apple2Activity activity, View convertView) {
+ convertView = _basicView(activity, this, convertView);
+ _addPopupIcon(activity, this, convertView);
+ return convertView;
+ }
+
+ @Override
+ public void handleSelection(final Apple2Activity activity, final Apple2AbstractMenu settingsMenu, boolean isChecked) {
+ final IMenuEnum self = this;
+ _alertDialogHandleSelection(activity, R.string.joystick_button_swipe_right_button, new String[]{
+ activity.getResources().getString(R.string.joystick_button_button_none),
+ activity.getResources().getString(R.string.joystick_button_button1),
+ activity.getResources().getString(R.string.joystick_button_button2),
+ activity.getResources().getString(R.string.joystick_button_button_both),
+ }, new IPreferenceLoadSave() {
+ @Override
+ public int intValue() {
+ return (int) Apple2Preferences.getJSONPref(self);
+ }
+
+ @Override
+ public void saveInt(int value) {
+ Apple2Preferences.setJSONPref(self, TouchJoystickButtons.values()[value].ordinal());
+ }
+ });
+ }
+ },
JOYSTICK_ADVANCED {
@Override
public final String getTitle(Apple2Activity activity) {
diff --git a/Android/app/src/main/res/values-de/strings.xml b/Android/app/src/main/res/values-de/strings.xml
index f5816afd..ba240d42 100644
--- a/Android/app/src/main/res/values-de/strings.xml
+++ b/Android/app/src/main/res/values-de/strings.xml
@@ -209,5 +209,9 @@
Robotron Tasten…
Lode Runner Tasten…
Start game with Ctrl-K to activate keyboard
+ Swipe left fire
+ Swipe right fire
+ Button to fire on swipe left
+ Button to fire on swipe right
diff --git a/Android/app/src/main/res/values-es/strings.xml b/Android/app/src/main/res/values-es/strings.xml
index da71f848..2e2b5718 100644
--- a/Android/app/src/main/res/values-es/strings.xml
+++ b/Android/app/src/main/res/values-es/strings.xml
@@ -209,5 +209,9 @@
Tecla para Robotron…
Lode Runner keys…
Start game with Ctrl-K to activate keyboard
+ Swipe left fire
+ Swipe right fire
+ Button to fire on swipe left
+ Button to fire on swipe right
diff --git a/Android/app/src/main/res/values-fr/strings.xml b/Android/app/src/main/res/values-fr/strings.xml
index b3edbd23..9862b10e 100644
--- a/Android/app/src/main/res/values-fr/strings.xml
+++ b/Android/app/src/main/res/values-fr/strings.xml
@@ -209,5 +209,9 @@
Touches Robotron…
Touches Lode Runner…
Start game with Ctrl-K to activate keyboard
+ Swipe left fire
+ Swipe right fire
+ Button to fire on swipe left
+ Button to fire on swipe right
diff --git a/Android/app/src/main/res/values/strings.xml b/Android/app/src/main/res/values/strings.xml
index 7a11a4a8..2a7a1d0b 100644
--- a/Android/app/src/main/res/values/strings.xml
+++ b/Android/app/src/main/res/values/strings.xml
@@ -209,5 +209,9 @@
Robotron keys…
Lode Runner keys…
Start game with Ctrl-K to activate keyboard
+ Swipe left fire
+ Swipe right fire
+ Button to fire on swipe right
+ Button to fire on swipe left
diff --git a/Android/assets/release_notes.txt b/Android/assets/release_notes.txt
index bc1ee1c3..3413c21c 100644
--- a/Android/assets/release_notes.txt
+++ b/Android/assets/release_notes.txt
@@ -9,7 +9,11 @@ TOUCH KEYPAD JOYSTICK:
- Improved emulation fidelity and auto-repeat response
- Full left and right side rosette configurations
-- More key pre-sets for popular games (L0de Runner, R0b0tr0n 2084, ...)
+- More presets for popular games (L0de Runner, R0b0tr0n 2084, ...)
+
+TOUCH JOYSTICK:
+
+- Can now configure a button to fire on left/right swipe (instead of just touch down, swipe up/down)
GENERAL INFO:
diff --git a/src/prefs.h b/src/prefs.h
index f7ada629..cbd3acea 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -52,17 +52,13 @@
#define PREF_AXIS_SENSITIVITY "axisSensitivity"
#define PREF_JOY_SWIPE_NORTH_CHAR "jsSwipeNorthChar"
#define PREF_JOY_SWIPE_SOUTH_CHAR "jsSwipeSouthChar"
+#define PREF_JOY_SWIPE_WEST_CHAR "jsSwipeWestChar"
+#define PREF_JOY_SWIPE_EAST_CHAR "jsSwipeEastChar"
#define PREF_JOY_TAP_DELAY "jsTapDelayFrames"
#define PREF_JOY_TOUCHDOWN_CHAR "jsTouchDownChar"
#define PREF_KPAD_FAST_AUTOREPEAT "kpFastAutoRepeat"
#define PREF_KPAD_AXIS_ROSETTE "kpAxisRosette"
#define PREF_KPAD_BUTT_ROSETTE "kpButtRosette"
-#define PREF_KPAD_SWIPE_NORTH_CHAR "kpSwipeNorthChar"
-#define PREF_KPAD_SWIPE_NORTH_SCAN "kpSwipeNorthScancode"
-#define PREF_KPAD_SWIPE_SOUTH_CHAR "kpSwipeSouthChar"
-#define PREF_KPAD_SWIPE_SOUTH_SCAN "kpSwipeSouthScancode"
-#define PREF_KPAD_TOUCHDOWN_CHAR "kpTouchDownChar"
-#define PREF_KPAD_TOUCHDOWN_SCAN "kpTouchDownScancode"
#define PREF_SCREEN_DIVISION "screenDivider"
#define PREF_SHOW_CONTROLS "showControls"
#define PREF_SWITCH_THRESHOLD "switchThreshold"
diff --git a/src/video/gltouchjoy_joy.c b/src/video/gltouchjoy_joy.c
index efb6982a..a88d391b 100644
--- a/src/video/gltouchjoy_joy.c
+++ b/src/video/gltouchjoy_joy.c
@@ -27,13 +27,14 @@ static struct {
touchjoy_button_type_t touchDownChar;
touchjoy_button_type_t northChar;
touchjoy_button_type_t southChar;
+ touchjoy_button_type_t westChar;
+ touchjoy_button_type_t eastChar;
uint8_t currJoyButtonValue0;
uint8_t currJoyButtonValue1;
uint8_t currButtonDisplayChar;
uint8_t lastButtonDisplayChar;
- bool buttonThresholdExceeded;
bool justTapConfigured;
} joys = { 0 };
@@ -46,6 +47,7 @@ static interface_device_t touchjoy_variant(void) {
static inline void _reset_button_state(void) {
run_args.joy_button0 = 0;
run_args.joy_button1 = 0;
+ joys.currButtonDisplayChar = ' ';
}
static inline void _reset_axis_state(void) {
@@ -180,7 +182,6 @@ static void touchjoy_buttonDown(void) {
SPIN_LOCK_FULL(&joys.spinlock);
TOUCH_JOY_LOG("\t\tjoy buttonDown acquire");
- joys.buttonThresholdExceeded = false;
joys.tapDelayFrameCount = 0UL;
_reset_button_state();
@@ -203,26 +204,27 @@ static void _touchjoy_buttonMove(int dx, int dy) {
bool shouldFire = false;
touchjoy_button_type_t theButtonChar = joys.touchDownChar;
- int delta = abs(dy);
- if (!joys.buttonThresholdExceeded) {
- if (delta >= joyglobals.switchThreshold) {
- // unambiguous intent : user swiped beyond threshold
- joys.buttonThresholdExceeded = true;
- shouldFire = true;
- theButtonChar = (dy < 0) ? joys.northChar : joys.southChar;
+ int c = (int)sqrtf(dx * dx + dy * dy);
+ if (c >= joyglobals.switchThreshold) {
+ // unambiguous intent : user swiped beyond threshold
+ shouldFire = true;
+
+ touchjoy_button_type_t yChar = (dy < 0) ? joys.northChar : joys.southChar;
+ touchjoy_button_type_t xChar = (dx < 0) ? joys.westChar : joys.eastChar;
+
+ if (abs(dx) <= abs(dy)) {
+ // prefer y axis ...
+ theButtonChar = (yChar != TOUCH_NONE) ? yChar : xChar;
+ } else {
+ // prefer x axis ...
+ theButtonChar = (xChar != TOUCH_NONE) ? xChar : yChar;
}
} else {
-
- if (delta < joyglobals.switchThreshold) {
- // 2019/04/20 NOTE: originally we did not re-zero back to touchDownChar ... this allowed a progression between
- // southChar/northChar (or vice-versa)
- //
- // touchDownChar should be fired on a tap or long-press (once we swipe beyond the threshold, we should only switch
- // between northChar and southChar)
-
- //shouldFire = true;
- joys.buttonThresholdExceeded = false;
- }
+ // 2019/04/20 NOTE: originally we did not re-zero back to touchDownChar ... this allowed a progression between
+ // southChar/northChar (or vice-versa)
+ //
+ // touchDownChar should be fired on a tap or long-press (once we swipe beyond the threshold, we should only switch
+ // between northChar and southChar)
}
if (shouldFire) {
@@ -272,10 +274,14 @@ static void touchjoy_prefsChanged(const char *domain) {
joys.touchDownChar = prefs_parseLongValue(domain, PREF_JOY_TOUCHDOWN_CHAR, &lVal, /*base:*/10) ? lVal : TOUCH_BUTTON1;
joys.northChar = prefs_parseLongValue(domain, PREF_JOY_SWIPE_NORTH_CHAR, &lVal, /*base:*/10) ? lVal : TOUCH_BOTH;
joys.southChar = prefs_parseLongValue(domain, PREF_JOY_SWIPE_SOUTH_CHAR, &lVal, /*base:*/10) ? lVal : TOUCH_BUTTON2;
+ joys.westChar = prefs_parseLongValue(domain, PREF_JOY_SWIPE_WEST_CHAR , &lVal, /*base:*/10) ? lVal : TOUCH_NONE;
+ joys.eastChar = prefs_parseLongValue(domain, PREF_JOY_SWIPE_EAST_CHAR , &lVal, /*base:*/10) ? lVal : TOUCH_NONE;
joys.justTapConfigured = (joys.touchDownChar != TOUCH_NONE) &&
(joys.northChar == TOUCH_NONE) &&
- (joys.southChar == TOUCH_NONE);
+ (joys.southChar == TOUCH_NONE) &&
+ (joys.westChar == TOUCH_NONE) &&
+ (joys.eastChar == TOUCH_NONE);
}
static uint8_t *touchjoy_axisRosetteChars(void) {