summaryrefslogtreecommitdiffstats
path: root/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java264
1 files changed, 264 insertions, 0 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java
new file mode 100644
index 000000000..875719311
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java
@@ -0,0 +1,264 @@
+/**
+ * Copyright 2013 Dolphin Emulator Project
+ * Licensed under GPLv2+
+ * Refer to the license.txt file included.
+ */
+
+package org.yuzu.yuzu_emu.overlay;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.view.MotionEvent;
+
+import org.yuzu.yuzu_emu.NativeLibrary.ButtonType;
+import org.yuzu.yuzu_emu.utils.EmulationMenuSettings;
+
+/**
+ * Custom {@link BitmapDrawable} that is capable
+ * of storing it's own ID.
+ */
+public final class InputOverlayDrawableJoystick {
+ private final int[] axisIDs = {0, 0, 0, 0};
+ private final float[] axises = {0f, 0f};
+ private int trackId = -1;
+ private int mJoystickType;
+ private int mControlPositionX, mControlPositionY;
+ private int mPreviousTouchX, mPreviousTouchY;
+ private int mWidth;
+ private int mHeight;
+ private Rect mVirtBounds;
+ private Rect mOrigBounds;
+ private BitmapDrawable mOuterBitmap;
+ private BitmapDrawable mDefaultStateInnerBitmap;
+ private BitmapDrawable mPressedStateInnerBitmap;
+ private BitmapDrawable mBoundsBoxBitmap;
+ private boolean mPressedState = false;
+
+ /**
+ * Constructor
+ *
+ * @param res {@link Resources} instance.
+ * @param bitmapOuter {@link Bitmap} which represents the outer non-movable part of the joystick.
+ * @param bitmapInnerDefault {@link Bitmap} which represents the default inner movable part of the joystick.
+ * @param bitmapInnerPressed {@link Bitmap} which represents the pressed inner movable part of the joystick.
+ * @param rectOuter {@link Rect} which represents the outer joystick bounds.
+ * @param rectInner {@link Rect} which represents the inner joystick bounds.
+ * @param joystick Identifier for which joystick this is.
+ */
+ public InputOverlayDrawableJoystick(Resources res, Bitmap bitmapOuter,
+ Bitmap bitmapInnerDefault, Bitmap bitmapInnerPressed,
+ Rect rectOuter, Rect rectInner, int joystick) {
+ axisIDs[0] = joystick + 1; // Up
+ axisIDs[1] = joystick + 2; // Down
+ axisIDs[2] = joystick + 3; // Left
+ axisIDs[3] = joystick + 4; // Right
+ mJoystickType = joystick;
+
+ mOuterBitmap = new BitmapDrawable(res, bitmapOuter);
+ mDefaultStateInnerBitmap = new BitmapDrawable(res, bitmapInnerDefault);
+ mPressedStateInnerBitmap = new BitmapDrawable(res, bitmapInnerPressed);
+ mBoundsBoxBitmap = new BitmapDrawable(res, bitmapOuter);
+ mWidth = bitmapOuter.getWidth();
+ mHeight = bitmapOuter.getHeight();
+
+ setBounds(rectOuter);
+ mDefaultStateInnerBitmap.setBounds(rectInner);
+ mPressedStateInnerBitmap.setBounds(rectInner);
+ mVirtBounds = getBounds();
+ mOrigBounds = mOuterBitmap.copyBounds();
+ mBoundsBoxBitmap.setAlpha(0);
+ mBoundsBoxBitmap.setBounds(getVirtBounds());
+ SetInnerBounds();
+ }
+
+ /**
+ * Gets this InputOverlayDrawableJoystick's button ID.
+ *
+ * @return this InputOverlayDrawableJoystick's button ID.
+ */
+ public int getId() {
+ return mJoystickType;
+ }
+
+ public void draw(Canvas canvas) {
+ mOuterBitmap.draw(canvas);
+ getCurrentStateBitmapDrawable().draw(canvas);
+ mBoundsBoxBitmap.draw(canvas);
+ }
+
+ public void TrackEvent(MotionEvent event) {
+ int pointerIndex = event.getActionIndex();
+
+ switch (event.getAction() & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_POINTER_DOWN:
+ if (getBounds().contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex))) {
+ mPressedState = true;
+ mOuterBitmap.setAlpha(0);
+ mBoundsBoxBitmap.setAlpha(255);
+ if (EmulationMenuSettings.getJoystickRelCenter()) {
+ getVirtBounds().offset((int) event.getX(pointerIndex) - getVirtBounds().centerX(),
+ (int) event.getY(pointerIndex) - getVirtBounds().centerY());
+ }
+ mBoundsBoxBitmap.setBounds(getVirtBounds());
+ trackId = event.getPointerId(pointerIndex);
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_POINTER_UP:
+ if (trackId == event.getPointerId(pointerIndex)) {
+ mPressedState = false;
+ axises[0] = axises[1] = 0.0f;
+ mOuterBitmap.setAlpha(255);
+ mBoundsBoxBitmap.setAlpha(0);
+ setVirtBounds(new Rect(mOrigBounds.left, mOrigBounds.top, mOrigBounds.right,
+ mOrigBounds.bottom));
+ setBounds(new Rect(mOrigBounds.left, mOrigBounds.top, mOrigBounds.right,
+ mOrigBounds.bottom));
+ SetInnerBounds();
+ trackId = -1;
+ }
+ break;
+ }
+
+ if (trackId == -1)
+ return;
+
+ for (int i = 0; i < event.getPointerCount(); i++) {
+ if (trackId == event.getPointerId(i)) {
+ float touchX = event.getX(i);
+ float touchY = event.getY(i);
+ float maxY = getVirtBounds().bottom;
+ float maxX = getVirtBounds().right;
+ touchX -= getVirtBounds().centerX();
+ maxX -= getVirtBounds().centerX();
+ touchY -= getVirtBounds().centerY();
+ maxY -= getVirtBounds().centerY();
+ final float AxisX = touchX / maxX;
+ final float AxisY = touchY / maxY;
+
+ // Clamp the circle pad input to a circle
+ final float angle = (float) Math.atan2(AxisY, AxisX);
+ float radius = (float) Math.sqrt(AxisX * AxisX + AxisY * AxisY);
+ if(radius > 1.0f)
+ {
+ radius = 1.0f;
+ }
+ axises[0] = ((float)Math.cos(angle) * radius);
+ axises[1] = ((float)Math.sin(angle) * radius);
+ SetInnerBounds();
+ }
+ }
+ }
+
+ public boolean onConfigureTouch(MotionEvent event) {
+ int pointerIndex = event.getActionIndex();
+ int fingerPositionX = (int) event.getX(pointerIndex);
+ int fingerPositionY = (int) event.getY(pointerIndex);
+
+ int scale = 1;
+ if (mJoystickType == ButtonType.STICK_C) {
+ // C-stick is scaled down to be half the size of the circle pad
+ scale = 2;
+ }
+
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ mPreviousTouchX = fingerPositionX;
+ mPreviousTouchY = fingerPositionY;
+ break;
+ case MotionEvent.ACTION_MOVE:
+ int deltaX = fingerPositionX - mPreviousTouchX;
+ int deltaY = fingerPositionY - mPreviousTouchY;
+ mControlPositionX += deltaX;
+ mControlPositionY += deltaY;
+ setBounds(new Rect(mControlPositionX, mControlPositionY,
+ mOuterBitmap.getIntrinsicWidth() / scale + mControlPositionX,
+ mOuterBitmap.getIntrinsicHeight() / scale + mControlPositionY));
+ setVirtBounds(new Rect(mControlPositionX, mControlPositionY,
+ mOuterBitmap.getIntrinsicWidth() / scale + mControlPositionX,
+ mOuterBitmap.getIntrinsicHeight() / scale + mControlPositionY));
+ SetInnerBounds();
+ setOrigBounds(new Rect(new Rect(mControlPositionX, mControlPositionY,
+ mOuterBitmap.getIntrinsicWidth() / scale + mControlPositionX,
+ mOuterBitmap.getIntrinsicHeight() / scale + mControlPositionY)));
+ mPreviousTouchX = fingerPositionX;
+ mPreviousTouchY = fingerPositionY;
+ break;
+ }
+ return true;
+ }
+
+
+ public float[] getAxisValues() {
+ return axises;
+ }
+
+ public int[] getAxisIDs() {
+ return axisIDs;
+ }
+
+ private void SetInnerBounds() {
+ int X = getVirtBounds().centerX() + (int) ((axises[0]) * (getVirtBounds().width() / 2));
+ int Y = getVirtBounds().centerY() + (int) ((axises[1]) * (getVirtBounds().height() / 2));
+
+ if (mJoystickType == ButtonType.STICK_LEFT) {
+ X += 1;
+ Y += 1;
+ }
+
+ if (X > getVirtBounds().centerX() + (getVirtBounds().width() / 2))
+ X = getVirtBounds().centerX() + (getVirtBounds().width() / 2);
+ if (X < getVirtBounds().centerX() - (getVirtBounds().width() / 2))
+ X = getVirtBounds().centerX() - (getVirtBounds().width() / 2);
+ if (Y > getVirtBounds().centerY() + (getVirtBounds().height() / 2))
+ Y = getVirtBounds().centerY() + (getVirtBounds().height() / 2);
+ if (Y < getVirtBounds().centerY() - (getVirtBounds().height() / 2))
+ Y = getVirtBounds().centerY() - (getVirtBounds().height() / 2);
+
+ int width = mPressedStateInnerBitmap.getBounds().width() / 2;
+ int height = mPressedStateInnerBitmap.getBounds().height() / 2;
+ mDefaultStateInnerBitmap.setBounds(X - width, Y - height, X + width, Y + height);
+ mPressedStateInnerBitmap.setBounds(mDefaultStateInnerBitmap.getBounds());
+ }
+
+ public void setPosition(int x, int y) {
+ mControlPositionX = x;
+ mControlPositionY = y;
+ }
+
+ private BitmapDrawable getCurrentStateBitmapDrawable() {
+ return mPressedState ? mPressedStateInnerBitmap : mDefaultStateInnerBitmap;
+ }
+
+ public Rect getBounds() {
+ return mOuterBitmap.getBounds();
+ }
+
+ public void setBounds(Rect bounds) {
+ mOuterBitmap.setBounds(bounds);
+ }
+
+ private void setOrigBounds(Rect bounds) {
+ mOrigBounds = bounds;
+ }
+
+ private Rect getVirtBounds() {
+ return mVirtBounds;
+ }
+
+ private void setVirtBounds(Rect bounds) {
+ mVirtBounds = bounds;
+ }
+
+ public int getWidth() {
+ return mWidth;
+ }
+
+ public int getHeight() {
+ return mHeight;
+ }
+}