From 17645fabb3cefdfc885b8c564ef050ea453119e3 Mon Sep 17 00:00:00 2001 From: SachinVin Date: Sat, 30 May 2020 19:18:23 +0530 Subject: [PATCH] android : Fix touchscreen for reals Adds proper multitouch tracking for touchscreen --- .../org/citra/citra_emu/NativeLibrary.java | 3 ++- .../citra/citra_emu/overlay/InputOverlay.java | 27 ++++++++++++++----- .../src/main/jni/emu_window/emu_window.cpp | 9 ++++--- .../app/src/main/jni/emu_window/emu_window.h | 2 +- src/android/app/src/main/jni/native.cpp | 4 +-- src/android/app/src/main/jni/native.h | 2 +- 6 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java index 866c4e806..464336592 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java @@ -96,8 +96,9 @@ public final class NativeLibrary { * @param x_axis The value of the x-axis. * @param y_axis The value of the y-axis * @param pressed To identify if the touch held down or released. + * @return true if the pointer is within the touchscreen */ - public static native void onTouchEvent(float x_axis, float y_axis, boolean pressed); + public static native boolean onTouchEvent(float x_axis, float y_axis, boolean pressed); /** * Handles touch movement. diff --git a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.java b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.java index 13a7079d6..97de95ab7 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.java @@ -50,6 +50,8 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener { private SharedPreferences mPreferences; + // Stores the ID of the pointer that interacted with the 3DS touchscreen. + private int mTouchscreenPointerId = -1; /** * Constructor * @@ -64,6 +66,9 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener { defaultOverlay(); } + // Reset 3ds touchscreen pointer ID + mTouchscreenPointerId = -1; + // Load the controls. refreshControls(); @@ -343,18 +348,26 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: - NativeLibrary.onTouchEvent(event.getX(pointerIndex), event.getY(pointerIndex), true); - break; - case MotionEvent.ACTION_MOVE: - NativeLibrary.onTouchMoved(event.getX(), event.getY()); + if (NativeLibrary.onTouchEvent(event.getX(pointerIndex), event.getY(pointerIndex), true)) { + mTouchscreenPointerId = event.getPointerId(pointerIndex); + } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: - // We dont really care where the touch has been released. We only care whether it has been - // released or not. - NativeLibrary.onTouchEvent(0, 0, false); + if (mTouchscreenPointerId == event.getPointerId(pointerIndex)) { + // We don't really care where the touch has been released. We only care whether it has been + // released or not. + NativeLibrary.onTouchEvent(0, 0, false); + mTouchscreenPointerId = -1; + } break; } + + for (int i = 0; i < event.getPointerCount(); i++) { + if (mTouchscreenPointerId == event.getPointerId(i)) { + NativeLibrary.onTouchMoved(event.getX(i), event.getY(i)); + } + } } for (InputOverlayDrawableButton button : overlayButtons) { diff --git a/src/android/app/src/main/jni/emu_window/emu_window.cpp b/src/android/app/src/main/jni/emu_window/emu_window.cpp index 270611f5a..9ba9605ac 100644 --- a/src/android/app/src/main/jni/emu_window/emu_window.cpp +++ b/src/android/app/src/main/jni/emu_window/emu_window.cpp @@ -81,12 +81,13 @@ void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { render_window = surface; } -void EmuWindow_Android::OnTouchEvent(int x, int y, bool pressed) { +bool EmuWindow_Android::OnTouchEvent(int x, int y, bool pressed) { if (pressed) { - TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); - } else { - TouchReleased(); + return TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); } + + TouchReleased(); + return true; } void EmuWindow_Android::OnTouchMoved(int x, int y) { diff --git a/src/android/app/src/main/jni/emu_window/emu_window.h b/src/android/app/src/main/jni/emu_window/emu_window.h index 175df340e..f27b462ff 100644 --- a/src/android/app/src/main/jni/emu_window/emu_window.h +++ b/src/android/app/src/main/jni/emu_window/emu_window.h @@ -42,7 +42,7 @@ public: void OnSurfaceChanged(ANativeWindow* surface); /// Handles touch event that occur.(Touched or released) - void OnTouchEvent(int x, int y, bool pressed); + bool OnTouchEvent(int x, int y, bool pressed); /// Handles movement of touch pointer void OnTouchMoved(int x, int y); diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 4deec7138..04b7f774e 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -351,10 +351,10 @@ jboolean Java_org_citra_citra_1emu_NativeLibrary_onGamePadAxisEvent(JNIEnv* env, InputManager::ButtonHandler()->AnalogButtonEvent(axis_id, axis_val)); } -void Java_org_citra_citra_1emu_NativeLibrary_onTouchEvent(JNIEnv* env, +jboolean Java_org_citra_citra_1emu_NativeLibrary_onTouchEvent(JNIEnv* env, [[maybe_unused]] jclass clazz, jfloat x, jfloat y, jboolean pressed) { - window->OnTouchEvent((int)x, (int)y, (bool)pressed); + return static_cast(window->OnTouchEvent(static_cast(x + 0.5), static_cast(y + 0.5), pressed)); } void Java_org_citra_citra_1emu_NativeLibrary_onTouchMoved(JNIEnv* env, diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h index 79de5e843..11f526215 100644 --- a/src/android/app/src/main/jni/native.h +++ b/src/android/app/src/main/jni/native.h @@ -32,7 +32,7 @@ JNIEXPORT jboolean JNICALL Java_org_citra_citra_1emu_NativeLibrary_onGamePadMove JNIEXPORT jboolean JNICALL Java_org_citra_citra_1emu_NativeLibrary_onGamePadAxisEvent( JNIEnv* env, jclass clazz, jstring j_device, jint axis_id, jfloat axis_val); -JNIEXPORT void JNICALL Java_org_citra_citra_1emu_NativeLibrary_onTouchEvent(JNIEnv* env, +JNIEXPORT jboolean JNICALL Java_org_citra_citra_1emu_NativeLibrary_onTouchEvent(JNIEnv* env, jclass clazz, jfloat x, jfloat y, jboolean pressed);