From 0bc88696277d4e31e97aaa2eba535db09493a2d1 Mon Sep 17 00:00:00 2001 From: Aaron Culliney Date: Thu, 30 Jul 2015 21:36:22 -0700 Subject: [PATCH] nativeOnTouch() now returns various state flags - Allows playing of a key click sound if a keyboard item tapped - Improves stovepiping the native request to show the Android main menu --- .../org/deadc0de/apple2ix/Apple2Activity.java | 27 +++++++++++++++--- Android/jni/jnihooks.c | 24 ++++------------ src/interface.c | 2 +- src/interface.h | 11 +++++++- src/video/glnode.c | 10 +++---- src/video/glnode.h | 4 +-- src/video/gltouchjoy.c | 11 ++++---- src/video/gltouchkbd.c | 25 ++++++++++------- src/video/gltouchmenu.c | 28 ++++++++++--------- src/video/video.h | 1 - 10 files changed, 83 insertions(+), 60 deletions(-) diff --git a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Activity.java b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Activity.java index a5570b1e..199be143 100644 --- a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Activity.java +++ b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Activity.java @@ -17,6 +17,7 @@ import android.content.DialogInterface; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.Rect; +import android.media.AudioManager; import android.os.Build; import android.os.Bundle; import android.os.StrictMode; @@ -63,6 +64,13 @@ public class Apple2Activity extends Activity { System.loadLibrary("apple2ix"); } + public final static int NATIVE_TOUCH_HANDLED = (1 << 0); + public final static int NATIVE_TOUCH_REQUEST_SHOW_MENU = (1 << 1); + public final static int NATIVE_TOUCH_KEY_TAP = (1 << 4); + public final static int NATIVE_TOUCH_KBD = (1 << 5); + public final static int NATIVE_TOUCH_JOY = (1 << 6); + public final static int NATIVE_TOUCH_MENU = (1 << 7); + private native void nativeOnCreate(String dataDir, int sampleRate, int monoBufferSize, int stereoBufferSize); private native void nativeGraphicsInitialized(int width, int height); @@ -81,7 +89,7 @@ public class Apple2Activity extends Activity { public native void nativeOnQuit(); - public native boolean nativeOnTouch(int action, int pointerCount, int pointerIndex, float[] xCoords, float[] yCoords); + public native long nativeOnTouch(int action, int pointerCount, int pointerIndex, float[] xCoords, float[] yCoords); public native void nativeReboot(); @@ -400,12 +408,23 @@ public class Apple2Activity extends Activity { mYCoords[i] = event.getY(i); } - boolean nativeHandled = nativeOnTouch(action, pointerCount, pointerIndex, mXCoords, mYCoords); - if (nativeHandled) { + long nativeFlags = nativeOnTouch(action, pointerCount, pointerIndex, mXCoords, mYCoords); + + if ((nativeFlags & NATIVE_TOUCH_HANDLED) == 0) { break; } - mainMenu.show(); + if ((nativeFlags & NATIVE_TOUCH_REQUEST_SHOW_MENU) != 0) { + mainMenu.show(); + } + + if ((nativeFlags & NATIVE_TOUCH_KEY_TAP) != 0) { + AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE); + if (am != null) { + am.playSoundEffect(AudioManager.FX_KEY_CLICK); + } + } + } while (false); return super.onTouchEvent(event); diff --git a/Android/jni/jnihooks.c b/Android/jni/jnihooks.c index d9766037..13ef36f2 100644 --- a/Android/jni/jnihooks.c +++ b/Android/jni/jnihooks.c @@ -30,8 +30,6 @@ enum { ANDROID_ACTION_POINTER_UP = 0x6, }; -static bool nativeRequestsShowMainMenu = false; - #if TESTING static bool _run_tests(void) { char *local_argv[] = { @@ -80,10 +78,6 @@ static inline int _androidTouchEvent2JoystickEvent(jint action) { } } -static void _nativeRequestsShowMainMenu(void) { - nativeRequestsShowMainMenu = true; -} - // ---------------------------------------------------------------------------- // JNI functions @@ -281,16 +275,16 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnKeyUp(JNIEnv *env, jobjec #endif } -jboolean Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnTouch(JNIEnv *env, jobject obj, jint action, jint pointerCount, jint pointerIndex, jfloatArray xCoords, jfloatArray yCoords) { +jlong Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnTouch(JNIEnv *env, jobject obj, jint action, jint pointerCount, jint pointerIndex, jfloatArray xCoords, jfloatArray yCoords) { //LOG("nativeOnTouch : %d/%d/%d :", action, pointerCount, pointerIndex); if (UNLIKELY(emulator_shutting_down)) { - return true; + return 0x0LL; } if (cpu_isPaused()) { LOG("UNPAUSING NATIVE CPU THREAD"); cpu_resume(); - return true; + return 0x0LL; } jfloat *x_coords = (*env)->GetFloatArrayElements(env, xCoords, 0); @@ -302,17 +296,11 @@ jboolean Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnTouch(JNIEnv *env, jo // LOG("\t[%f,%f]", x_coords[i], y_coords[i]); //} - interface_onTouchEvent(joyaction, pointerCount, pointerIndex, x_coords, y_coords); - - bool consumed = true; // default assume that native can handle touch event (except for explicit request to show main menu) - if (nativeRequestsShowMainMenu) { - nativeRequestsShowMainMenu = false; - consumed = false; - } + int64_t flags = interface_onTouchEvent(joyaction, pointerCount, pointerIndex, x_coords, y_coords); (*env)->ReleaseFloatArrayElements(env, xCoords, x_coords, 0); (*env)->ReleaseFloatArrayElements(env, yCoords, y_coords, 0); - return consumed; + return flags; } void Java_org_deadc0de_apple2ix_Apple2Activity_nativeChooseDisk(JNIEnv *env, jobject obj, jstring jPath, jboolean driveA, jboolean readOnly) { @@ -343,6 +331,6 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeChooseDisk(JNIEnv *env, job __attribute__((constructor(CTOR_PRIORITY_LATE))) static void _init_jnihooks(void) { - video_backend->hostenv_showMainMenu = &_nativeRequestsShowMainMenu; + // ... } diff --git a/src/interface.c b/src/interface.c index 76212f8f..19c86030 100644 --- a/src/interface.c +++ b/src/interface.c @@ -18,7 +18,7 @@ #if INTERFACE_TOUCH // touch interface managed elsewhere -bool (*interface_onTouchEvent)(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) = NULL; +int64_t (*interface_onTouchEvent)(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) = NULL; bool (*interface_isTouchMenuAvailable)(void) = NULL; void (*interface_setTouchMenuEnabled)(bool enabled) = NULL; void (*interface_setTouchMenuVisibility)(float alpha) = NULL; diff --git a/src/interface.h b/src/interface.h index d194166e..2c7a7f9a 100644 --- a/src/interface.h +++ b/src/interface.h @@ -54,8 +54,17 @@ typedef enum interface_touch_event_t { TOUCH_POINTER_UP, } interface_touch_event_t; +typedef enum interface_touch_event_flags { + TOUCH_FLAGS_HANDLED = (1<<0), + TOUCH_FLAGS_REQUEST_HOST_MENU = (1<<1), + TOUCH_FLAGS_KEY_TAP = (1<<4), + TOUCH_FLAGS_KBD = (1<<5), + TOUCH_FLAGS_JOY = (1<<6), + TOUCH_FLAGS_MENU = (1<<7), +} interface_touch_event_flags; + // handle touch event -extern bool (*interface_onTouchEvent)(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords); +extern int64_t (*interface_onTouchEvent)(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords); // is the touch menu module itself available? extern bool (*interface_isTouchMenuAvailable)(void); diff --git a/src/video/glnode.c b/src/video/glnode.c index 6c03c78f..073994b4 100644 --- a/src/video/glnode.c +++ b/src/video/glnode.c @@ -86,17 +86,17 @@ void glnode_reshapeNodes(int w, int h) { } #if INTERFACE_TOUCH -bool glnode_onTouchEvent(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) { +int64_t glnode_onTouchEvent(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) { glnode_array_node_s *p = glNodes; - bool handled = false; + int64_t flags = 0x0; while (p) { - handled = p->node.onTouchEvent(action, pointer_count, pointer_idx, x_coords, y_coords); - if (handled) { + flags = p->node.onTouchEvent(action, pointer_count, pointer_idx, x_coords, y_coords); + if (flags & TOUCH_FLAGS_HANDLED) { break; } p = p->next; } - return handled; + return flags; } #endif diff --git a/src/video/glnode.h b/src/video/glnode.h index 575457b8..129195e1 100644 --- a/src/video/glnode.h +++ b/src/video/glnode.h @@ -29,7 +29,7 @@ typedef struct GLNode { void (*shutdown)(void); void (*render)(void); #if INTERFACE_TOUCH - bool (*onTouchEvent)(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords); + int (*onTouchEvent)(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords); #endif void (*reshape)(int w, int h); } GLNode; @@ -51,7 +51,7 @@ void glnode_reshapeNodes(int w, int h); #if INTERFACE_TOUCH // distribute touch event to node which can handle it (in render order) -bool glnode_onTouchEvent(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords); +int64_t glnode_onTouchEvent(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords); #endif #endif diff --git a/src/video/gltouchjoy.c b/src/video/gltouchjoy.c index 46ff0a53..f2da892b 100644 --- a/src/video/gltouchjoy.c +++ b/src/video/gltouchjoy.c @@ -538,16 +538,16 @@ static inline void _move_button_axis(int x, int y) { } } -static bool gltouchjoy_onTouchEvent(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) { +static int64_t gltouchjoy_onTouchEvent(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) { if (!isAvailable) { - return false; + return 0x0LL; } if (!isEnabled) { - return false; + return 0x0LL; } if (!ownsScreen) { - return false; + return 0x0LL; } bool axisConsumed = false; @@ -648,7 +648,8 @@ static bool gltouchjoy_onTouchEvent(interface_touch_event_t action, int pointer_ clock_gettime(CLOCK_MONOTONIC, &buttons.timingBegin); } - return (axisConsumed || buttonConsumed); + return TOUCH_FLAGS_HANDLED | TOUCH_FLAGS_JOY; +#warning FIXME TODO ... do we care about (axisConsumed || buttonConsumed)? } static bool gltouchjoy_isTouchJoystickAvailable(void) { diff --git a/src/video/gltouchkbd.c b/src/video/gltouchkbd.c index c9a0747b..27ab9736 100644 --- a/src/video/gltouchkbd.c +++ b/src/video/gltouchkbd.c @@ -278,7 +278,7 @@ static inline void _redraw_selected(int col, int row) { } } -static inline void _tap_key_at_point(float x, float y) { +static inline bool _tap_key_at_point(float x, float y) { GLModelHUDKeyboard *hudKeyboard = (GLModelHUDKeyboard *)kbd.model->custom; if (!_is_point_on_keyboard(x, y)) { @@ -288,7 +288,7 @@ static inline void _tap_key_at_point(float x, float y) { _redraw_unselected(kbd.selectedCol, kbd.selectedRow); kbd.selectedCol = -1; kbd.selectedRow = -1; - return; + return false; } // get current key, col, row @@ -301,6 +301,7 @@ static inline void _tap_key_at_point(float x, float y) { // handle key + bool handled = true; bool isASCII = false; bool isCTRL = false; switch (key) { @@ -313,6 +314,7 @@ static inline void _tap_key_at_point(float x, float y) { case ICONTEXT_NONACTIONABLE: key = -1; + handled = false; break; case ICONTEXT_CTRL: @@ -399,6 +401,7 @@ static inline void _tap_key_at_point(float x, float y) { // draw current selected key _redraw_selected(kbd.selectedCol, kbd.selectedRow); + return handled; } // ---------------------------------------------------------------------------- @@ -620,21 +623,23 @@ static void gltouchkbd_reshape(int w, int h) { touchport.kbdH = touchport.kbdYMax - touchport.kbdY; } -static bool gltouchkbd_onTouchEvent(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) { +static int64_t gltouchkbd_onTouchEvent(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) { if (!isAvailable) { - return false; + return 0x0LL; } if (!isEnabled) { - return false; + return 0x0LL; } if (!ownsScreen) { - return false; + return 0x0LL; } float x = x_coords[pointer_idx]; float y = y_coords[pointer_idx]; + int64_t flags = TOUCH_FLAGS_KBD | TOUCH_FLAGS_HANDLED; + switch (action) { case TOUCH_DOWN: case TOUCH_POINTER_DOWN: @@ -645,21 +650,21 @@ static bool gltouchkbd_onTouchEvent(interface_touch_event_t action, int pointer_ case TOUCH_UP: case TOUCH_POINTER_UP: - _tap_key_at_point(x, y); + flags |= _tap_key_at_point(x, y) ? TOUCH_FLAGS_KEY_TAP : 0x0LL; break; case TOUCH_CANCEL: LOG("---KBD TOUCH CANCEL"); - return false; + return 0x0LL; default: LOG("!!!KBD UNKNOWN TOUCH EVENT : %d", action); - return false; + return 0x0LL; } clock_gettime(CLOCK_MONOTONIC, &kbd.timingBegin); - return true; + return flags; } // ---------------------------------------------------------------------------- diff --git a/src/video/gltouchmenu.c b/src/video/gltouchmenu.c index 3d6ca37a..c2110b23 100644 --- a/src/video/gltouchmenu.c +++ b/src/video/gltouchmenu.c @@ -286,9 +286,9 @@ static inline bool _sprout_menu(float x, float y) { } } -static inline bool _tap_menu_item(float x, float y) { +static inline int64_t _tap_menu_item(float x, float y) { if (! (_is_point_on_left_menu(x, y) || _is_point_on_right_menu(x, y)) ) { - return false; + return 0x0LL; } int col = -1; @@ -298,6 +298,7 @@ static inline bool _tap_menu_item(float x, float y) { int selectedItem = topMenuTemplate[row][col]; + int64_t flags = TOUCH_FLAGS_KEY_TAP; switch (selectedItem) { case MOUSETEXT_LEFT: @@ -312,9 +313,7 @@ static inline bool _tap_menu_item(float x, float y) { case MOUSETEXT_CHECKMARK: LOG("showing main menu..."); - if (video_backend->hostenv_showMainMenu) { - video_backend->hostenv_showMainMenu(); - } + flags |= TOUCH_FLAGS_REQUEST_HOST_MENU; _hide_top_right(); break; @@ -351,12 +350,13 @@ static inline bool _tap_menu_item(float x, float y) { case ICONTEXT_NONACTIONABLE: default: LOG("nonactionable ..."); + flags = 0x0LL; _hide_top_left(); _hide_top_right(); break; } - return true; + return flags; } // ---------------------------------------------------------------------------- @@ -507,13 +507,13 @@ static void gltouchmenu_reshape(int w, int h) { } } -static bool gltouchmenu_onTouchEvent(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) { +static int gltouchmenu_onTouchEvent(interface_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) { if (!isAvailable) { - return false; + return 0x0; } if (!isEnabled) { - return false; + return 0x0; } //LOG("gltouchmenu_onTouchEvent ..."); @@ -522,6 +522,7 @@ static bool gltouchmenu_onTouchEvent(interface_touch_event_t action, int pointer float y = y_coords[pointer_idx]; bool handled = (_is_point_on_left_menu(x, y) || _is_point_on_right_menu(x, y)); + int flags = TOUCH_FLAGS_MENU; switch (action) { case TOUCH_DOWN: @@ -534,23 +535,24 @@ static bool gltouchmenu_onTouchEvent(interface_touch_event_t action, int pointer case TOUCH_UP: case TOUCH_POINTER_UP: - _tap_menu_item(x, y); + flags |= _tap_menu_item(x, y); break; case TOUCH_CANCEL: LOG("---MENU TOUCH CANCEL"); - break; + return 0x0; default: LOG("!!!MENU UNKNOWN TOUCH EVENT : %d", action); - break; + return 0x0; } if (handled) { clock_gettime(CLOCK_MONOTONIC, &timingBegin); + flags |= TOUCH_FLAGS_HANDLED; } - return handled; + return flags; } // ---------------------------------------------------------------------------- diff --git a/src/video/video.h b/src/video/video.h index d480331a..a597556c 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -27,7 +27,6 @@ typedef struct video_backend_s { void (*shutdown)(void); // touch HUD functions - void (*hostenv_showMainMenu)(void); void (*animation_showTouchKeyboard)(void); void (*animation_hideTouchKeyboard)(void); void (*animation_showTouchJoystick)(void);