committed by
bunnei
2 changed files with 232 additions and 276 deletions
-
276src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableDpad.java
-
232src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableDpad.kt
@ -1,276 +0,0 @@ |
|||||
/** |
|
||||
* Copyright 2016 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.ButtonState; |
|
||||
|
|
||||
/** |
|
||||
* Custom {@link BitmapDrawable} that is capable |
|
||||
* of storing it's own ID. |
|
||||
*/ |
|
||||
public final class InputOverlayDrawableDpad { |
|
||||
public static final float VIRT_AXIS_DEADZONE = 0.5f; |
|
||||
// The ID identifying what type of button this Drawable represents. |
|
||||
private int mUpButtonId; |
|
||||
private int mDownButtonId; |
|
||||
private int mLeftButtonId; |
|
||||
private int mRightButtonId; |
|
||||
private int mTrackId; |
|
||||
private int mControlPositionX, mControlPositionY; |
|
||||
private int mWidth; |
|
||||
private int mHeight; |
|
||||
private BitmapDrawable mDefaultStateBitmap; |
|
||||
private BitmapDrawable mPressedOneDirectionStateBitmap; |
|
||||
private BitmapDrawable mPressedTwoDirectionsStateBitmap; |
|
||||
private boolean mUpButtonState; |
|
||||
private boolean mDownButtonState; |
|
||||
private boolean mLeftButtonState; |
|
||||
private boolean mRightButtonState; |
|
||||
|
|
||||
/** |
|
||||
* Constructor |
|
||||
* |
|
||||
* @param res {@link Resources} instance. |
|
||||
* @param defaultStateBitmap {@link Bitmap} of the default state. |
|
||||
* @param pressedOneDirectionStateBitmap {@link Bitmap} of the pressed state in one direction. |
|
||||
* @param pressedTwoDirectionsStateBitmap {@link Bitmap} of the pressed state in two direction. |
|
||||
* @param buttonUp Identifier for the up button. |
|
||||
* @param buttonDown Identifier for the down button. |
|
||||
* @param buttonLeft Identifier for the left button. |
|
||||
* @param buttonRight Identifier for the right button. |
|
||||
*/ |
|
||||
public InputOverlayDrawableDpad(Resources res, |
|
||||
Bitmap defaultStateBitmap, |
|
||||
Bitmap pressedOneDirectionStateBitmap, |
|
||||
Bitmap pressedTwoDirectionsStateBitmap, |
|
||||
int buttonUp, int buttonDown, |
|
||||
int buttonLeft, int buttonRight) { |
|
||||
mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap); |
|
||||
mPressedOneDirectionStateBitmap = new BitmapDrawable(res, pressedOneDirectionStateBitmap); |
|
||||
mPressedTwoDirectionsStateBitmap = new BitmapDrawable(res, pressedTwoDirectionsStateBitmap); |
|
||||
|
|
||||
mWidth = mDefaultStateBitmap.getIntrinsicWidth(); |
|
||||
mHeight = mDefaultStateBitmap.getIntrinsicHeight(); |
|
||||
|
|
||||
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; |
|
||||
final boolean up_state = mUpButtonState; |
|
||||
final boolean down_state = mDownButtonState; |
|
||||
final boolean left_state = mLeftButtonState; |
|
||||
final boolean right_state = mRightButtonState; |
|
||||
|
|
||||
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 up_state != mUpButtonState || down_state != mDownButtonState || left_state != mLeftButtonState || right_state != mRightButtonState; |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
public void draw(Canvas canvas) { |
|
||||
int px = mControlPositionX + (getWidth() / 2); |
|
||||
int py = mControlPositionY + (getHeight() / 2); |
|
||||
|
|
||||
// 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(90, 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); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Gets one of the InputOverlayDrawableDpad's button IDs. |
|
||||
* |
|
||||
* @return the requested InputOverlayDrawableDpad's button ID. |
|
||||
*/ |
|
||||
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 int getUpStatus() { |
|
||||
return mUpButtonState ? ButtonState.PRESSED : ButtonState.RELEASED; |
|
||||
} |
|
||||
|
|
||||
public int getDownStatus() { |
|
||||
return mDownButtonState ? ButtonState.PRESSED : ButtonState.RELEASED; |
|
||||
} |
|
||||
|
|
||||
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) { |
|
||||
mControlPositionX = x; |
|
||||
mControlPositionY = y; |
|
||||
} |
|
||||
|
|
||||
public void setBounds(int left, int top, int right, int bottom) { |
|
||||
mDefaultStateBitmap.setBounds(left, top, right, bottom); |
|
||||
mPressedOneDirectionStateBitmap.setBounds(left, top, right, bottom); |
|
||||
mPressedTwoDirectionsStateBitmap.setBounds(left, top, right, bottom); |
|
||||
} |
|
||||
|
|
||||
public Rect getBounds() { |
|
||||
return mDefaultStateBitmap.getBounds(); |
|
||||
} |
|
||||
|
|
||||
public int getWidth() { |
|
||||
return mWidth; |
|
||||
} |
|
||||
|
|
||||
public int getHeight() { |
|
||||
return mHeight; |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,232 @@ |
|||||
|
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.ButtonState |
||||
|
|
||||
|
/** |
||||
|
* Custom [BitmapDrawable] that is capable |
||||
|
* of storing it's own ID. |
||||
|
* |
||||
|
* @param res [Resources] instance. |
||||
|
* @param defaultStateBitmap [Bitmap] of the default state. |
||||
|
* @param pressedOneDirectionStateBitmap [Bitmap] of the pressed state in one direction. |
||||
|
* @param pressedTwoDirectionsStateBitmap [Bitmap] of the pressed state in two direction. |
||||
|
* @param buttonUp Identifier for the up button. |
||||
|
* @param buttonDown Identifier for the down button. |
||||
|
* @param buttonLeft Identifier for the left button. |
||||
|
* @param buttonRight Identifier for the right button. |
||||
|
*/ |
||||
|
class InputOverlayDrawableDpad( |
||||
|
res: Resources, |
||||
|
defaultStateBitmap: Bitmap, |
||||
|
pressedOneDirectionStateBitmap: Bitmap, |
||||
|
pressedTwoDirectionsStateBitmap: Bitmap, |
||||
|
buttonUp: Int, |
||||
|
buttonDown: Int, |
||||
|
buttonLeft: Int, |
||||
|
buttonRight: Int |
||||
|
) { |
||||
|
/** |
||||
|
* Gets one of the InputOverlayDrawableDpad's button IDs. |
||||
|
* |
||||
|
* @return the requested InputOverlayDrawableDpad's button ID. |
||||
|
*/ |
||||
|
// The ID identifying what type of button this Drawable represents. |
||||
|
val upId: Int |
||||
|
val downId: Int |
||||
|
val leftId: Int |
||||
|
val rightId: Int |
||||
|
var trackId: Int |
||||
|
private var controlPositionX = 0 |
||||
|
private var controlPositionY = 0 |
||||
|
val width: Int |
||||
|
val height: Int |
||||
|
private val defaultStateBitmap: BitmapDrawable |
||||
|
private val pressedOneDirectionStateBitmap: BitmapDrawable |
||||
|
private val pressedTwoDirectionsStateBitmap: BitmapDrawable |
||||
|
private var upButtonState = false |
||||
|
private var downButtonState = false |
||||
|
private var leftButtonState = false |
||||
|
private var rightButtonState = false |
||||
|
|
||||
|
init { |
||||
|
this.defaultStateBitmap = BitmapDrawable(res, defaultStateBitmap) |
||||
|
this.pressedOneDirectionStateBitmap = BitmapDrawable(res, pressedOneDirectionStateBitmap) |
||||
|
this.pressedTwoDirectionsStateBitmap = BitmapDrawable(res, pressedTwoDirectionsStateBitmap) |
||||
|
width = this.defaultStateBitmap.intrinsicWidth |
||||
|
height = this.defaultStateBitmap.intrinsicHeight |
||||
|
upId = buttonUp |
||||
|
downId = buttonDown |
||||
|
leftId = buttonLeft |
||||
|
rightId = buttonRight |
||||
|
trackId = -1 |
||||
|
} |
||||
|
|
||||
|
fun updateStatus(event: MotionEvent, dpad_slide: Boolean): Boolean { |
||||
|
val pointerIndex = event.actionIndex |
||||
|
val xPosition = event.getX(pointerIndex).toInt() |
||||
|
val yPosition = event.getY(pointerIndex).toInt() |
||||
|
val pointerId = event.getPointerId(pointerIndex) |
||||
|
val motionEvent = event.action and MotionEvent.ACTION_MASK |
||||
|
val isActionDown = |
||||
|
motionEvent == MotionEvent.ACTION_DOWN || motionEvent == MotionEvent.ACTION_POINTER_DOWN |
||||
|
val isActionUp = |
||||
|
motionEvent == MotionEvent.ACTION_UP || motionEvent == MotionEvent.ACTION_POINTER_UP |
||||
|
if (isActionDown) { |
||||
|
if (!bounds.contains(xPosition, yPosition)) { |
||||
|
return false |
||||
|
} |
||||
|
trackId = pointerId |
||||
|
} |
||||
|
if (isActionUp) { |
||||
|
if (trackId != pointerId) { |
||||
|
return false |
||||
|
} |
||||
|
trackId = -1 |
||||
|
upButtonState = false |
||||
|
downButtonState = false |
||||
|
leftButtonState = false |
||||
|
rightButtonState = false |
||||
|
return true |
||||
|
} |
||||
|
if (trackId == -1) { |
||||
|
return false |
||||
|
} |
||||
|
if (!dpad_slide && !isActionDown) { |
||||
|
return false |
||||
|
} |
||||
|
for (i in 0 until event.pointerCount) { |
||||
|
if (trackId != event.getPointerId(i)) { |
||||
|
continue |
||||
|
} |
||||
|
|
||||
|
var touchX = event.getX(i) |
||||
|
var touchY = event.getY(i) |
||||
|
var maxY = bounds.bottom.toFloat() |
||||
|
var maxX = bounds.right.toFloat() |
||||
|
touchX -= bounds.centerX().toFloat() |
||||
|
maxX -= bounds.centerX().toFloat() |
||||
|
touchY -= bounds.centerY().toFloat() |
||||
|
maxY -= bounds.centerY().toFloat() |
||||
|
val axisX = touchX / maxX |
||||
|
val axisY = touchY / maxY |
||||
|
val oldUpState = upButtonState |
||||
|
val oldDownState = downButtonState |
||||
|
val oldLeftState = leftButtonState |
||||
|
val oldRightState = rightButtonState |
||||
|
|
||||
|
upButtonState = axisY < -VIRT_AXIS_DEADZONE |
||||
|
downButtonState = axisY > VIRT_AXIS_DEADZONE |
||||
|
leftButtonState = axisX < -VIRT_AXIS_DEADZONE |
||||
|
rightButtonState = axisX > VIRT_AXIS_DEADZONE |
||||
|
return oldUpState != upButtonState || oldDownState != downButtonState || oldLeftState != leftButtonState || oldRightState != rightButtonState |
||||
|
} |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
fun draw(canvas: Canvas) { |
||||
|
val px = controlPositionX + width / 2 |
||||
|
val py = controlPositionY + height / 2 |
||||
|
|
||||
|
// Pressed up |
||||
|
if (upButtonState && !leftButtonState && !rightButtonState) { |
||||
|
pressedOneDirectionStateBitmap.draw(canvas) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// Pressed down |
||||
|
if (downButtonState && !leftButtonState && !rightButtonState) { |
||||
|
canvas.save() |
||||
|
canvas.rotate(180f, px.toFloat(), py.toFloat()) |
||||
|
pressedOneDirectionStateBitmap.draw(canvas) |
||||
|
canvas.restore() |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// Pressed left |
||||
|
if (leftButtonState && !upButtonState && !downButtonState) { |
||||
|
canvas.save() |
||||
|
canvas.rotate(270f, px.toFloat(), py.toFloat()) |
||||
|
pressedOneDirectionStateBitmap.draw(canvas) |
||||
|
canvas.restore() |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// Pressed right |
||||
|
if (rightButtonState && !upButtonState && !downButtonState) { |
||||
|
canvas.save() |
||||
|
canvas.rotate(90f, px.toFloat(), py.toFloat()) |
||||
|
pressedOneDirectionStateBitmap.draw(canvas) |
||||
|
canvas.restore() |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// Pressed up left |
||||
|
if (upButtonState && leftButtonState && !rightButtonState) { |
||||
|
pressedTwoDirectionsStateBitmap.draw(canvas) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// Pressed up right |
||||
|
if (upButtonState && !leftButtonState && rightButtonState) { |
||||
|
canvas.save() |
||||
|
canvas.rotate(90f, px.toFloat(), py.toFloat()) |
||||
|
pressedTwoDirectionsStateBitmap.draw(canvas) |
||||
|
canvas.restore() |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// Pressed down right |
||||
|
if (downButtonState && !leftButtonState && rightButtonState) { |
||||
|
canvas.save() |
||||
|
canvas.rotate(180f, px.toFloat(), py.toFloat()) |
||||
|
pressedTwoDirectionsStateBitmap.draw(canvas) |
||||
|
canvas.restore() |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// Pressed down left |
||||
|
if (downButtonState && leftButtonState && !rightButtonState) { |
||||
|
canvas.save() |
||||
|
canvas.rotate(270f, px.toFloat(), py.toFloat()) |
||||
|
pressedTwoDirectionsStateBitmap.draw(canvas) |
||||
|
canvas.restore() |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// Not pressed |
||||
|
defaultStateBitmap.draw(canvas) |
||||
|
} |
||||
|
|
||||
|
val upStatus: Int |
||||
|
get() = if (upButtonState) ButtonState.PRESSED else ButtonState.RELEASED |
||||
|
val downStatus: Int |
||||
|
get() = if (downButtonState) ButtonState.PRESSED else ButtonState.RELEASED |
||||
|
val leftStatus: Int |
||||
|
get() = if (leftButtonState) ButtonState.PRESSED else ButtonState.RELEASED |
||||
|
val rightStatus: Int |
||||
|
get() = if (rightButtonState) ButtonState.PRESSED else ButtonState.RELEASED |
||||
|
|
||||
|
fun setPosition(x: Int, y: Int) { |
||||
|
controlPositionX = x |
||||
|
controlPositionY = y |
||||
|
} |
||||
|
|
||||
|
fun setBounds(left: Int, top: Int, right: Int, bottom: Int) { |
||||
|
defaultStateBitmap.setBounds(left, top, right, bottom) |
||||
|
pressedOneDirectionStateBitmap.setBounds(left, top, right, bottom) |
||||
|
pressedTwoDirectionsStateBitmap.setBounds(left, top, right, bottom) |
||||
|
} |
||||
|
|
||||
|
val bounds: Rect |
||||
|
get() = defaultStateBitmap.bounds |
||||
|
|
||||
|
companion object { |
||||
|
const val VIRT_AXIS_DEADZONE = 0.5f |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue