Skip to content
Permalink
Browse files

Android: Add touch to move pointer in overlay

  • Loading branch information...
zackhow committed Oct 5, 2018
1 parent 3627ef8 commit 47d6406fd4492d46613dbb107bc3deb36fd3254d
@@ -102,14 +102,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
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 void toggleInputOverlayVisibility()
// 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()
@@ -43,6 +43,7 @@
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 boolean onTouch(View v, MotionEvent event)
}

int pointerIndex = event.getActionIndex();
// Tracks if any button/joystick is pressed down
boolean pressed = false;

for (InputOverlayDrawableButton button : overlayButtons)
{
@@ -142,6 +145,7 @@ public boolean onTouch(View v, MotionEvent event)
{
button.setPressedState(true);
button.setTrackId(event.getPointerId(pointerIndex));
pressed = true;
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(),
ButtonState.PRESSED);
}
@@ -154,6 +158,7 @@ public boolean onTouch(View v, MotionEvent event)
button.setPressedState(false);
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(),
ButtonState.RELEASED);
button.setTrackId(-1);
}
break;
}
@@ -166,35 +171,40 @@ public boolean onTouch(View v, MotionEvent event)
{
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,14 +218,19 @@ public boolean onTouch(View v, MotionEvent event)
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
ButtonState.RELEASED);
}
dpad.setTrackId(-1);
}
break;
}
}

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 boolean onTouch(View v, MotionEvent event)
}
}

// 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 void refreshControls()
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)
{
addGameCubeOverlayControls(orientation);
}
else if (mPreferences.getInt("wiiController", 3) == 4)
{
addClassicOverlayControls(orientation);
}
else
if (mPreferences.getBoolean("showInputOverlay", true))
{
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();
}

@@ -41,6 +41,7 @@
public InputOverlayDrawableButton(Resources res, Bitmap defaultStateBitmap,
Bitmap pressedStateBitmap, int buttonType)
{
mTrackId = -1;
mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap);
mPressedStateBitmap = new BitmapDrawable(res, pressedStateBitmap);
mButtonType = buttonType;
@@ -60,6 +60,7 @@ public InputOverlayDrawableDpad(Resources res,
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);
@@ -94,18 +94,19 @@ public void draw(Canvas canvas)
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)
{
case MotionEvent.ACTION_DOWN:
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 void TrackEvent(MotionEvent event)
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 void TrackEvent(MotionEvent event)
}

if (trackId == -1)
return;
return pressed;

for (int i = 0; i < event.getPointerCount(); i++)
{
@@ -158,6 +160,7 @@ public void TrackEvent(MotionEvent event)
SetInnerBounds();
}
}
return pressed;
}

public boolean onConfigureTouch(MotionEvent event)
@@ -274,4 +277,9 @@ public int getHeight()
{
return mHeight;
}

public int getTrackId()
{
return trackId;
}
}
@@ -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;
}
}
@@ -30,6 +30,7 @@ class Touchscreen : public Core::Device
{
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)
{

0 comments on commit 47d6406

Please sign in to comment.
You can’t perform that action at this time.