diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java index 96868f9657..c316a63b1d 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java @@ -376,110 +376,13 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener { } for (InputOverlayDrawableDpad dpad : overlayDpads) { - // Determine the button state to apply based on the MotionEvent action flag. - switch (event.getAction() & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_POINTER_DOWN: - // If a pointer enters the bounds of a button, press that button. - if (dpad.getBounds() - .contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex))) { - dpad.setTrackId(event.getPointerId(pointerIndex)); - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_POINTER_UP: - // If a pointer ends, release the buttons. - if (dpad.getTrackId() == event.getPointerId(pointerIndex)) { - for (int i = 0; i < 4; i++) { - dpad.setState(InputOverlayDrawableDpad.STATE_DEFAULT); - NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i), - NativeLibrary.ButtonState.RELEASED); - } - dpad.setTrackId(-1); - } - break; - } - - if (dpad.getTrackId() != -1) { - for (int i = 0; i < event.getPointerCount(); i++) { - if (dpad.getTrackId() == event.getPointerId(i)) { - float touchX = event.getX(i); - float touchY = event.getY(i); - float maxY = dpad.getBounds().bottom; - float maxX = dpad.getBounds().right; - touchX -= dpad.getBounds().centerX(); - maxX -= dpad.getBounds().centerX(); - touchY -= dpad.getBounds().centerY(); - maxY -= dpad.getBounds().centerY(); - final float AxisX = touchX / maxX; - final float AxisY = touchY / maxY; - - boolean up = false; - boolean down = false; - boolean left = false; - boolean right = false; - if (EmulationMenuSettings.getDpadSlideEnable() || - (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN || - (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) { - if (AxisY < -InputOverlayDrawableDpad.VIRT_AXIS_DEADZONE) { - NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(0), - NativeLibrary.ButtonState.PRESSED); - up = true; - } else { - NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(0), - NativeLibrary.ButtonState.RELEASED); - } - if (AxisY > InputOverlayDrawableDpad.VIRT_AXIS_DEADZONE) { - NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(1), - NativeLibrary.ButtonState.PRESSED); - down = true; - } else { - NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(1), - NativeLibrary.ButtonState.RELEASED); - } - if (AxisX < -InputOverlayDrawableDpad.VIRT_AXIS_DEADZONE) { - NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(2), - NativeLibrary.ButtonState.PRESSED); - left = true; - } else { - NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(2), - NativeLibrary.ButtonState.RELEASED); - } - if (AxisX > InputOverlayDrawableDpad.VIRT_AXIS_DEADZONE) { - NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(3), - NativeLibrary.ButtonState.PRESSED); - right = true; - } else { - NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(3), - NativeLibrary.ButtonState.RELEASED); - } - - // Set state - if (up) { - if (left) - dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_UP_LEFT); - else if (right) - dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_UP_RIGHT); - else - dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_UP); - } else if (down) { - if (left) - dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_DOWN_LEFT); - else if (right) - dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_DOWN_RIGHT); - else - dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_DOWN); - } else if (left) { - dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_LEFT); - } else if (right) { - dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_RIGHT); - } else { - dpad.setState(InputOverlayDrawableDpad.STATE_DEFAULT); - } - } - } - } + if (!dpad.updateStatus(event, EmulationMenuSettings.getDpadSlideEnable())) { + continue; } + NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getUpId(), dpad.getUpStatus()); + NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getDownId(), dpad.getDownStatus()); + NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getLeftId(), dpad.getLeftStatus()); + NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getRightId(), dpad.getRightStatus()); } for (InputOverlayDrawableJoystick joystick : overlayJoysticks) { diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableDpad.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableDpad.java index a14840d983..d8ee6895ba 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableDpad.java +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableDpad.java @@ -13,32 +13,30 @@ import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.view.MotionEvent; +import org.yuzu.yuzu_emu.NativeLibrary.ButtonState; + /** * Custom {@link BitmapDrawable} that is capable * of storing it's own ID. */ public final class InputOverlayDrawableDpad { - public static final int STATE_DEFAULT = 0; - public static final int STATE_PRESSED_UP = 1; - public static final int STATE_PRESSED_DOWN = 2; - public static final int STATE_PRESSED_LEFT = 3; - public static final int STATE_PRESSED_RIGHT = 4; - public static final int STATE_PRESSED_UP_LEFT = 5; - public static final int STATE_PRESSED_UP_RIGHT = 6; - public static final int STATE_PRESSED_DOWN_LEFT = 7; - public static final int STATE_PRESSED_DOWN_RIGHT = 8; public static final float VIRT_AXIS_DEADZONE = 0.5f; // The ID identifying what type of button this Drawable represents. - private int[] mButtonType = new int[4]; + private int mUpButtonId; + private int mDownButtonId; + private int mLeftButtonId; + private int mRightButtonId; private int mTrackId; - private int mPreviousTouchX, mPreviousTouchY; private int mControlPositionX, mControlPositionY; private int mWidth; private int mHeight; private BitmapDrawable mDefaultStateBitmap; private BitmapDrawable mPressedOneDirectionStateBitmap; private BitmapDrawable mPressedTwoDirectionsStateBitmap; - private int mPressState = STATE_DEFAULT; + private boolean mUpButtonState; + private boolean mDownButtonState; + private boolean mLeftButtonState; + private boolean mRightButtonState; /** * Constructor @@ -65,64 +63,147 @@ public final class InputOverlayDrawableDpad { mWidth = mDefaultStateBitmap.getIntrinsicWidth(); mHeight = mDefaultStateBitmap.getIntrinsicHeight(); - mButtonType[0] = buttonUp; - mButtonType[1] = buttonDown; - mButtonType[2] = buttonLeft; - mButtonType[3] = buttonRight; + mUpButtonId = buttonUp; + mDownButtonId = buttonDown; + mLeftButtonId = buttonLeft; + mRightButtonId = buttonRight; mTrackId = -1; } + public boolean updateStatus(MotionEvent event, boolean dpad_slide) { + int pointerIndex = event.getActionIndex(); + int xPosition = (int) event.getX(pointerIndex); + int yPosition = (int) event.getY(pointerIndex); + int pointerId = event.getPointerId(pointerIndex); + int motion_event = event.getAction() & MotionEvent.ACTION_MASK; + boolean isActionDown = motion_event == MotionEvent.ACTION_DOWN || motion_event == MotionEvent.ACTION_POINTER_DOWN; + boolean isActionUp = motion_event == MotionEvent.ACTION_UP || motion_event == MotionEvent.ACTION_POINTER_UP; + + if (isActionDown) { + if (!getBounds().contains(xPosition, yPosition)) { + return false; + } + mTrackId = pointerId; + } + + if (isActionUp) { + if (mTrackId != pointerId) { + return false; + } + mTrackId = -1; + mUpButtonState = false; + mDownButtonState = false; + mLeftButtonState = false; + mRightButtonState = false; + return true; + } + + if (mTrackId == -1) { + return false; + } + + if (!dpad_slide && !isActionDown) { + return false; + } + + for (int i = 0; i < event.getPointerCount(); i++) { + if (mTrackId != event.getPointerId(i)) { + continue; + } + float touchX = event.getX(i); + float touchY = event.getY(i); + float maxY = getBounds().bottom; + float maxX = getBounds().right; + touchX -= getBounds().centerX(); + maxX -= getBounds().centerX(); + touchY -= getBounds().centerY(); + maxY -= getBounds().centerY(); + final float AxisX = touchX / maxX; + final float AxisY = touchY / maxY; + + mUpButtonState = AxisY < -InputOverlayDrawableDpad.VIRT_AXIS_DEADZONE; + mDownButtonState = AxisY > InputOverlayDrawableDpad.VIRT_AXIS_DEADZONE; + mLeftButtonState = AxisX < -InputOverlayDrawableDpad.VIRT_AXIS_DEADZONE; + mRightButtonState = AxisX > InputOverlayDrawableDpad.VIRT_AXIS_DEADZONE; + return true; + } + + return false; + } + public void draw(Canvas canvas) { int px = mControlPositionX + (getWidth() / 2); int py = mControlPositionY + (getHeight() / 2); - switch (mPressState) { - case STATE_DEFAULT: - mDefaultStateBitmap.draw(canvas); - break; - case STATE_PRESSED_UP: - mPressedOneDirectionStateBitmap.draw(canvas); - break; - case STATE_PRESSED_RIGHT: - canvas.save(); - canvas.rotate(90, px, py); - mPressedOneDirectionStateBitmap.draw(canvas); - canvas.restore(); - break; - case STATE_PRESSED_DOWN: - canvas.save(); - canvas.rotate(180, px, py); - mPressedOneDirectionStateBitmap.draw(canvas); - canvas.restore(); - break; - case STATE_PRESSED_LEFT: - canvas.save(); - canvas.rotate(270, px, py); - mPressedOneDirectionStateBitmap.draw(canvas); - canvas.restore(); - break; - case STATE_PRESSED_UP_LEFT: - mPressedTwoDirectionsStateBitmap.draw(canvas); - break; - case STATE_PRESSED_UP_RIGHT: - canvas.save(); - canvas.rotate(90, px, py); - mPressedTwoDirectionsStateBitmap.draw(canvas); - canvas.restore(); - break; - case STATE_PRESSED_DOWN_RIGHT: - canvas.save(); - canvas.rotate(180, px, py); - mPressedTwoDirectionsStateBitmap.draw(canvas); - canvas.restore(); - break; - case STATE_PRESSED_DOWN_LEFT: - canvas.save(); - canvas.rotate(270, px, py); - mPressedTwoDirectionsStateBitmap.draw(canvas); - canvas.restore(); - break; + + // Pressed up + if (mUpButtonState && !mLeftButtonState && !mRightButtonState) { + mPressedOneDirectionStateBitmap.draw(canvas); + return; } + + // Pressed down + if (mDownButtonState && !mLeftButtonState && !mRightButtonState) { + canvas.save(); + canvas.rotate(180, px, py); + mPressedOneDirectionStateBitmap.draw(canvas); + canvas.restore(); + return; + } + + // Pressed left + if (mLeftButtonState && !mUpButtonState && !mDownButtonState) { + canvas.save(); + canvas.rotate(270, px, py); + mPressedOneDirectionStateBitmap.draw(canvas); + canvas.restore(); + return; + } + + // Pressed right + if (mRightButtonState && !mUpButtonState && !mDownButtonState) { + canvas.save(); + canvas.rotate(90, px, py); + mPressedOneDirectionStateBitmap.draw(canvas); + canvas.restore(); + return; + } + + // Pressed up left + if (mUpButtonState && mLeftButtonState && !mRightButtonState) { + mPressedTwoDirectionsStateBitmap.draw(canvas); + return; + } + + // Pressed up right + if (mUpButtonState && !mLeftButtonState && mRightButtonState) { + canvas.save(); + canvas.rotate(180, px, py); + mPressedTwoDirectionsStateBitmap.draw(canvas); + canvas.restore(); + return; + } + + // Pressed down left + if (mDownButtonState && mLeftButtonState && !mRightButtonState) { + canvas.save(); + canvas.rotate(270, px, py); + mPressedTwoDirectionsStateBitmap.draw(canvas); + canvas.restore(); + return; + } + + // Pressed down right + if (mDownButtonState && !mLeftButtonState && mRightButtonState) { + canvas.save(); + canvas.rotate(180, px, py); + mPressedTwoDirectionsStateBitmap.draw(canvas); + canvas.restore(); + return; + } + + // Not pressed + mDefaultStateBitmap.draw(canvas); } /** @@ -130,38 +211,40 @@ public final class InputOverlayDrawableDpad { * * @return the requested InputOverlayDrawableDpad's button ID. */ - public int getId(int direction) { - return mButtonType[direction]; + public int getUpId() { + return mUpButtonId; + } + + public int getDownId() { + return mDownButtonId; + } + + public int getLeftId() { + return mLeftButtonId; + } + + public int getRightId() { + return mRightButtonId; } public int getTrackId() { return mTrackId; } - public void setTrackId(int trackId) { - mTrackId = trackId; + public int getUpStatus() { + return mUpButtonState ? ButtonState.PRESSED : ButtonState.RELEASED; } - public boolean onConfigureTouch(MotionEvent event) { - int pointerIndex = event.getActionIndex(); - int fingerPositionX = (int) event.getX(pointerIndex); - int fingerPositionY = (int) event.getY(pointerIndex); - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - mPreviousTouchX = fingerPositionX; - mPreviousTouchY = fingerPositionY; - break; - case MotionEvent.ACTION_MOVE: - mControlPositionX += fingerPositionX - mPreviousTouchX; - mControlPositionY += fingerPositionY - mPreviousTouchY; - setBounds(mControlPositionX, mControlPositionY, getWidth() + mControlPositionX, - getHeight() + mControlPositionY); - mPreviousTouchX = fingerPositionX; - mPreviousTouchY = fingerPositionY; - break; + public int getDownStatus() { + return mDownButtonState ? ButtonState.PRESSED : ButtonState.RELEASED; + } - } - return true; + public int getLeftStatus() { + return mLeftButtonState ? ButtonState.PRESSED : ButtonState.RELEASED; + } + + public int getRightStatus() { + return mRightButtonState ? ButtonState.PRESSED : ButtonState.RELEASED; } public void setPosition(int x, int y) { @@ -186,8 +269,4 @@ public final class InputOverlayDrawableDpad { public int getHeight() { return mHeight; } - - public void setState(int pressState) { - mPressState = pressState; - } }