Android: Add touch to move pointer in overlay

This commit is contained in:
zackhow 2018-10-05 16:59:17 -04:00
parent 3627ef8a04
commit 47d6406fd4
7 changed files with 136 additions and 44 deletions

View File

@ -102,14 +102,6 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
surfaceView.getHolder().addCallback(this);
mInputOverlay = contents.findViewById(R.id.surface_input_overlay);
if (mInputOverlay != null)
{
// If the input overlay was previously disabled, then don't show it.
if (!mPreferences.getBoolean("showInputOverlay", true))
{
mInputOverlay.setVisibility(View.GONE);
}
}
Button doneButton = contents.findViewById(R.id.done_control_config);
if (doneButton != null)
@ -199,18 +191,14 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
// If the overlay is currently set to INVISIBLE
if (!mPreferences.getBoolean("showInputOverlay", false))
{
// Set it to VISIBLE
mInputOverlay.setVisibility(View.VISIBLE);
editor.putBoolean("showInputOverlay", true);
}
else
{
// Set it to INVISIBLE
mInputOverlay.setVisibility(View.GONE);
editor.putBoolean("showInputOverlay", false);
}
editor.apply();
editor.commit();
mInputOverlay.refreshControls();
}
public void refreshInputOverlay()

View File

@ -43,6 +43,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<>();
private final Set<InputOverlayDrawableDpad> overlayDpads = new HashSet<>();
private final Set<InputOverlayDrawableJoystick> overlayJoysticks = new HashSet<>();
private InputOverlayPointer overlayPointer;
private boolean mIsInEditMode = false;
private InputOverlayDrawableButton mButtonBeingConfigured;
@ -128,6 +129,8 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
}
int pointerIndex = event.getActionIndex();
// Tracks if any button/joystick is pressed down
boolean pressed = false;
for (InputOverlayDrawableButton button : overlayButtons)
{
@ -142,6 +145,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
{
button.setPressedState(true);
button.setTrackId(event.getPointerId(pointerIndex));
pressed = true;
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(),
ButtonState.PRESSED);
}
@ -154,6 +158,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
button.setPressedState(false);
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(),
ButtonState.RELEASED);
button.setTrackId(-1);
}
break;
}
@ -166,35 +171,40 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_MOVE:
// Up, Down, Left, Right
boolean[] pressed = {false, false, false, false};
// If a pointer enters the bounds of a button, press that button.
if (dpad.getBounds()
.contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex)))
{
dpad.setTrackId(event.getPointerId(pointerIndex));
pressed = true;
}
case MotionEvent.ACTION_MOVE:
if (dpad.getTrackId() == event.getPointerId(pointerIndex))
{
// Up, Down, Left, Right
boolean[] dpadPressed = {false, false, false, false};
if (dpad.getBounds().top + (dpad.getHeight() / 3) > (int) event.getY(pointerIndex))
pressed[0] = true;
dpadPressed[0] = true;
if (dpad.getBounds().bottom - (dpad.getHeight() / 3) < (int) event.getY(pointerIndex))
pressed[1] = true;
dpadPressed[1] = true;
if (dpad.getBounds().left + (dpad.getWidth() / 3) > (int) event.getX(pointerIndex))
pressed[2] = true;
dpadPressed[2] = true;
if (dpad.getBounds().right - (dpad.getWidth() / 3) < (int) event.getX(pointerIndex))
pressed[3] = true;
dpadPressed[3] = true;
// Release the buttons first, then press
for (int i = 0; i < pressed.length; i++)
if (!pressed[i])
for (int i = 0; i < dpadPressed.length; i++)
if (!dpadPressed[i])
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
ButtonState.RELEASED);
// Press buttons
for (int i = 0; i < pressed.length; i++)
if (pressed[i])
for (int i = 0; i < dpadPressed.length; i++)
if (dpadPressed[i])
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
ButtonState.PRESSED);
setDpadState(dpad, pressed[0], pressed[1], pressed[2], pressed[3]);
dpad.setTrackId(event.getPointerId(pointerIndex));
setDpadState(dpad, dpadPressed[0], dpadPressed[1], dpadPressed[2], dpadPressed[3]);
}
break;
case MotionEvent.ACTION_UP:
@ -208,6 +218,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
ButtonState.RELEASED);
}
dpad.setTrackId(-1);
}
break;
}
@ -215,7 +226,11 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
for (InputOverlayDrawableJoystick joystick : overlayJoysticks)
{
joystick.TrackEvent(event);
if (joystick.TrackEvent(event))
{
if (joystick.getTrackId() != -1)
pressed = true;
}
int[] axisIDs = joystick.getAxisIDs();
float[] axises = joystick.getAxisValues();
@ -225,6 +240,18 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
}
}
// No button/joystick pressed, safe to move pointer
if (!pressed && overlayPointer != null)
{
overlayPointer.onTouch(event);
float[] axises = overlayPointer.getAxisValues();
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice, ButtonType.WIIMOTE_IR + 2,
axises[0]);
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice, ButtonType.WIIMOTE_IR + 4,
axises[1]);
}
invalidate();
return true;
@ -617,24 +644,30 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ?
"-Portrait" : "";
// Add all the enabled overlay items back to the HashSet.
if (EmulationActivity.isGameCubeGame() || mPreferences.getInt("wiiController", 3) == 0)
if (mPreferences.getBoolean("showInputOverlay", true))
{
addGameCubeOverlayControls(orientation);
}
else if (mPreferences.getInt("wiiController", 3) == 4)
{
addClassicOverlayControls(orientation);
}
else
{
addWiimoteOverlayControls(orientation);
if (mPreferences.getInt("wiiController", 3) == 3)
// Add all the enabled overlay items back to the HashSet.
if (EmulationActivity.isGameCubeGame() || mPreferences.getInt("wiiController", 3) == 0)
{
addNunchukOverlayControls(orientation);
addGameCubeOverlayControls(orientation);
}
else if (mPreferences.getInt("wiiController", 3) == 4)
{
addClassicOverlayControls(orientation);
}
else
{
addWiimoteOverlayControls(orientation);
if (mPreferences.getInt("wiiController", 3) == 3)
{
addNunchukOverlayControls(orientation);
}
}
}
if (!EmulationActivity.isGameCubeGame())
overlayPointer = new InputOverlayPointer(this.getContext());
invalidate();
}

View File

@ -41,6 +41,7 @@ public final class InputOverlayDrawableButton
public InputOverlayDrawableButton(Resources res, Bitmap defaultStateBitmap,
Bitmap pressedStateBitmap, int buttonType)
{
mTrackId = -1;
mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap);
mPressedStateBitmap = new BitmapDrawable(res, pressedStateBitmap);
mButtonType = buttonType;

View File

@ -60,6 +60,7 @@ public final class InputOverlayDrawableDpad
int buttonUp, int buttonDown,
int buttonLeft, int buttonRight)
{
mTrackId = -1;
mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap);
mPressedOneDirectionStateBitmap = new BitmapDrawable(res, pressedOneDirectionStateBitmap);
mPressedTwoDirectionsStateBitmap = new BitmapDrawable(res, pressedTwoDirectionsStateBitmap);

View File

@ -94,10 +94,11 @@ public final class InputOverlayDrawableJoystick
mBoundsBoxBitmap.draw(canvas);
}
public void TrackEvent(MotionEvent event)
public boolean TrackEvent(MotionEvent event)
{
boolean reCenter = mPreferences.getBoolean("joystickRelCenter", true);
int pointerIndex = event.getActionIndex();
boolean pressed = false;
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
@ -105,7 +106,7 @@ public final class InputOverlayDrawableJoystick
case MotionEvent.ACTION_POINTER_DOWN:
if (getBounds().contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex)))
{
mPressedState = true;
mPressedState = pressed = true;
mOuterBitmap.setAlpha(0);
mBoundsBoxBitmap.setAlpha(255);
if (reCenter)
@ -121,6 +122,7 @@ public final class InputOverlayDrawableJoystick
case MotionEvent.ACTION_POINTER_UP:
if (trackId == event.getPointerId(pointerIndex))
{
pressed = true;
mPressedState = false;
axises[0] = axises[1] = 0.0f;
mOuterBitmap.setAlpha(255);
@ -136,7 +138,7 @@ public final class InputOverlayDrawableJoystick
}
if (trackId == -1)
return;
return pressed;
for (int i = 0; i < event.getPointerCount(); i++)
{
@ -158,6 +160,7 @@ public final class InputOverlayDrawableJoystick
SetInnerBounds();
}
}
return pressed;
}
public boolean onConfigureTouch(MotionEvent event)
@ -274,4 +277,9 @@ public final class InputOverlayDrawableJoystick
{
return mHeight;
}
public int getTrackId()
{
return trackId;
}
}

View File

@ -0,0 +1,60 @@
package org.dolphinemu.dolphinemu.overlay;
import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent;
public class InputOverlayPointer
{
private final float[] axes = {0f, 0f};
private float maxHeight;
private float maxWidth;
private int trackId = -1;
public InputOverlayPointer(Context context)
{
Display display = ((Activity) context).getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics();
display.getMetrics(outMetrics);
maxWidth = outMetrics.widthPixels / 2;
maxHeight = outMetrics.heightPixels / 2;
}
public boolean onTouch(MotionEvent event)
{
int pointerIndex = event.getActionIndex();
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
trackId = event.getPointerId(pointerIndex);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (trackId == event.getPointerId(pointerIndex))
trackId = -1;
break;
}
if (trackId == -1)
return false;
int x = (int) event.getX(event.findPointerIndex(trackId));
int y = (int) event.getY(event.findPointerIndex(trackId));
axes[0] = (y - maxHeight) / maxHeight;
axes[1] = (x - maxWidth) / maxWidth;
return false;
}
public float[] getAxisValues()
{
float[] ir = {0f, 0f};
ir[0] = axes[0];
ir[1] = axes[1];
return axes;
}
}

View File

@ -30,6 +30,7 @@ private:
{
public:
std::string GetName() const;
bool IsDetectable() override { return false; }
Axis(int padID, ButtonManager::ButtonType index, float neg = 1.0f)
: _padID(padID), _index(index), _neg(neg)
{