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