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) {