Android: Convert InputOverlayPointer to Kotlin

This commit is contained in:
Charles Lombardo 2023-06-03 19:06:59 -04:00
parent ddb0de0410
commit 0bd0fa4f44
2 changed files with 148 additions and 180 deletions

View File

@ -1,180 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.overlay;
import android.graphics.Rect;
import android.os.Handler;
import android.view.MotionEvent;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.features.input.model.InputOverrider;
import java.util.ArrayList;
public class InputOverlayPointer
{
public static final int MODE_DISABLED = 0;
public static final int MODE_FOLLOW = 1;
public static final int MODE_DRAG = 2;
private float mCurrentX = 0.0f;
private float mCurrentY = 0.0f;
private float mOldX = 0.0f;
private float mOldY = 0.0f;
private float mGameCenterX;
private float mGameCenterY;
private float mGameWidthHalfInv;
private float mGameHeightHalfInv;
private float mTouchStartX;
private float mTouchStartY;
private int mMode;
private boolean mRecenter;
private int mControllerIndex;
private boolean doubleTap = false;
private int mDoubleTapControl;
private int trackId = -1;
public static ArrayList<Integer> DOUBLE_TAP_OPTIONS = new ArrayList<>();
static
{
DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.WIIMOTE_BUTTON_A);
DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.WIIMOTE_BUTTON_B);
DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.WIIMOTE_BUTTON_2);
DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.CLASSIC_BUTTON_A);
}
public InputOverlayPointer(Rect surfacePosition, int doubleTapControl, int mode, boolean recenter,
int controllerIndex)
{
mDoubleTapControl = doubleTapControl;
mMode = mode;
mRecenter = recenter;
mControllerIndex = controllerIndex;
mGameCenterX = (surfacePosition.left + surfacePosition.right) / 2.0f;
mGameCenterY = (surfacePosition.top + surfacePosition.bottom) / 2.0f;
float gameWidth = surfacePosition.right - surfacePosition.left;
float gameHeight = surfacePosition.bottom - surfacePosition.top;
// Adjusting for device's black bars.
float surfaceAR = gameWidth / gameHeight;
float gameAR = NativeLibrary.GetGameAspectRatio();
if (gameAR <= surfaceAR)
{
// Black bars on left/right
gameWidth = gameHeight * gameAR;
}
else
{
// Black bars on top/bottom
gameHeight = gameWidth / gameAR;
}
mGameWidthHalfInv = 1.0f / (gameWidth * 0.5f);
mGameHeightHalfInv = 1.0f / (gameHeight * 0.5f);
}
public void onTouch(MotionEvent event)
{
int action = event.getActionMasked();
boolean firstPointer = action != MotionEvent.ACTION_POINTER_DOWN &&
action != MotionEvent.ACTION_POINTER_UP;
int pointerIndex = firstPointer ? 0 : event.getActionIndex();
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
trackId = event.getPointerId(pointerIndex);
mTouchStartX = event.getX(pointerIndex);
mTouchStartY = event.getY(pointerIndex);
touchPress();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (trackId == event.getPointerId(pointerIndex))
trackId = -1;
if (mMode == MODE_DRAG)
updateOldAxes();
if (mRecenter)
reset();
break;
}
int eventPointerIndex = event.findPointerIndex(trackId);
if (trackId == -1 || eventPointerIndex == -1)
return;
if (mMode == MODE_FOLLOW)
{
mCurrentX = (event.getX(eventPointerIndex) - mGameCenterX) * mGameWidthHalfInv;
mCurrentY = (event.getY(eventPointerIndex) - mGameCenterY) * mGameHeightHalfInv;
}
else if (mMode == MODE_DRAG)
{
mCurrentX = mOldX +
(event.getX(eventPointerIndex) - mTouchStartX) * mGameWidthHalfInv;
mCurrentY = mOldY +
(event.getY(eventPointerIndex) - mTouchStartY) * mGameHeightHalfInv;
}
}
private void touchPress()
{
if (mMode != MODE_DISABLED)
{
if (doubleTap)
{
InputOverrider.setControlState(mControllerIndex, mDoubleTapControl, 1.0);
new Handler().postDelayed(() -> InputOverrider.setControlState(mControllerIndex,
mDoubleTapControl, 0.0),
50);
}
else
{
doubleTap = true;
new Handler().postDelayed(() -> doubleTap = false, 300);
}
}
}
private void updateOldAxes()
{
mOldX = mCurrentX;
mOldY = mCurrentY;
}
private void reset()
{
mCurrentX = mCurrentY = mOldX = mOldY = 0.0f;
}
public float getX()
{
return mCurrentX;
}
public float getY()
{
return mCurrentY;
}
public void setMode(int mode)
{
mMode = mode;
if (mode == MODE_DRAG)
updateOldAxes();
}
public void setRecenter(boolean recenter)
{
mRecenter = recenter;
}
}

View File

@ -0,0 +1,148 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.overlay
import android.graphics.Rect
import android.os.Handler
import android.os.Looper
import android.view.MotionEvent
import org.dolphinemu.dolphinemu.NativeLibrary
import org.dolphinemu.dolphinemu.features.input.model.InputOverrider
class InputOverlayPointer(
surfacePosition: Rect,
private val doubleTapControl: Int,
private var mode: Int,
private var recenter: Boolean,
private val controllerIndex: Int
) {
var x = 0.0f
var y = 0.0f
private var oldX = 0.0f
private var oldY = 0.0f
private val gameCenterX: Float
private val gameCenterY: Float
private val gameWidthHalfInv: Float
private val gameHeightHalfInv: Float
private var touchStartX = 0f
private var touchStartY = 0f
private var doubleTap = false
private var trackId = -1
init {
gameCenterX = (surfacePosition.left + surfacePosition.right) / 2f
gameCenterY = (surfacePosition.top + surfacePosition.bottom) / 2f
var gameWidth = (surfacePosition.right - surfacePosition.left).toFloat()
var gameHeight = (surfacePosition.bottom - surfacePosition.top).toFloat()
// Adjusting for device's black bars.
val surfaceAR = gameWidth / gameHeight
val gameAR = NativeLibrary.GetGameAspectRatio()
if (gameAR <= surfaceAR) {
// Black bars on left/right
gameWidth = gameHeight * gameAR
} else {
// Black bars on top/bottom
gameHeight = gameWidth / gameAR
}
gameWidthHalfInv = 1f / (gameWidth * 0.5f)
gameHeightHalfInv = 1f / (gameHeight * 0.5f)
}
fun onTouch(event: MotionEvent) {
val action = event.actionMasked
val firstPointer = action != MotionEvent.ACTION_POINTER_DOWN &&
action != MotionEvent.ACTION_POINTER_UP
val pointerIndex = if (firstPointer) 0 else event.actionIndex
when (action) {
MotionEvent.ACTION_DOWN,
MotionEvent.ACTION_POINTER_DOWN -> {
trackId = event.getPointerId(pointerIndex)
touchStartX = event.getX(pointerIndex)
touchStartY = event.getY(pointerIndex)
touchPress()
}
MotionEvent.ACTION_UP,
MotionEvent.ACTION_POINTER_UP -> {
if (trackId == event.getPointerId(pointerIndex))
trackId = -1
if (mode == MODE_DRAG)
updateOldAxes()
if (recenter)
reset()
}
}
val eventPointerIndex = event.findPointerIndex(trackId)
if (trackId == -1 || eventPointerIndex == -1)
return
if (mode == MODE_FOLLOW) {
x = (event.getX(eventPointerIndex) - gameCenterX) * gameWidthHalfInv
y = (event.getY(eventPointerIndex) - gameCenterY) * gameHeightHalfInv
} else if (mode == MODE_DRAG) {
x = oldX + (event.getX(eventPointerIndex) - touchStartX) * gameWidthHalfInv
y = oldY + (event.getY(eventPointerIndex) - touchStartY) * gameHeightHalfInv
}
}
private fun touchPress() {
if (mode != MODE_DISABLED) {
if (doubleTap) {
InputOverrider.setControlState(controllerIndex, doubleTapControl, 1.0)
Handler(Looper.myLooper()!!).postDelayed(
{
InputOverrider.setControlState(controllerIndex, doubleTapControl, 0.0)
},
50
)
} else {
doubleTap = true
Handler(Looper.myLooper()!!).postDelayed({ doubleTap = false }, 300)
}
}
}
private fun updateOldAxes() {
oldX = x
oldY = y
}
private fun reset() {
oldY = 0.0f
oldX = 0.0f
y = 0.0f
x = 0.0f
}
fun setMode(mode: Int) {
this.mode = mode
if (mode == MODE_DRAG)
updateOldAxes()
}
fun setRecenter(recenter: Boolean) {
this.recenter = recenter
}
companion object {
const val MODE_DISABLED = 0
const val MODE_FOLLOW = 1
const val MODE_DRAG = 2
@JvmField
var DOUBLE_TAP_OPTIONS = arrayListOf(
NativeLibrary.ButtonType.WIIMOTE_BUTTON_A,
NativeLibrary.ButtonType.WIIMOTE_BUTTON_B,
NativeLibrary.ButtonType.WIIMOTE_BUTTON_2,
NativeLibrary.ButtonType.CLASSIC_BUTTON_A
)
}
}