forked from suyu/suyu
android: Convert InputOverlayDrawableDpad to Kotlin
This commit is contained in:
parent
0177e908e9
commit
d85678a80f
2 changed files with 232 additions and 276 deletions
|
@ -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
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue