Android: Add touch to move pointer in overlay
This commit is contained in:
parent
3627ef8a04
commit
47d6406fd4
|
@ -102,14 +102,6 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
||||||
surfaceView.getHolder().addCallback(this);
|
surfaceView.getHolder().addCallback(this);
|
||||||
|
|
||||||
mInputOverlay = contents.findViewById(R.id.surface_input_overlay);
|
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);
|
Button doneButton = contents.findViewById(R.id.done_control_config);
|
||||||
if (doneButton != null)
|
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 the overlay is currently set to INVISIBLE
|
||||||
if (!mPreferences.getBoolean("showInputOverlay", false))
|
if (!mPreferences.getBoolean("showInputOverlay", false))
|
||||||
{
|
{
|
||||||
// Set it to VISIBLE
|
|
||||||
mInputOverlay.setVisibility(View.VISIBLE);
|
|
||||||
editor.putBoolean("showInputOverlay", true);
|
editor.putBoolean("showInputOverlay", true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Set it to INVISIBLE
|
|
||||||
mInputOverlay.setVisibility(View.GONE);
|
|
||||||
editor.putBoolean("showInputOverlay", false);
|
editor.putBoolean("showInputOverlay", false);
|
||||||
}
|
}
|
||||||
|
editor.commit();
|
||||||
editor.apply();
|
mInputOverlay.refreshControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshInputOverlay()
|
public void refreshInputOverlay()
|
||||||
|
|
|
@ -43,6 +43,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<>();
|
private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<>();
|
||||||
private final Set<InputOverlayDrawableDpad> overlayDpads = new HashSet<>();
|
private final Set<InputOverlayDrawableDpad> overlayDpads = new HashSet<>();
|
||||||
private final Set<InputOverlayDrawableJoystick> overlayJoysticks = new HashSet<>();
|
private final Set<InputOverlayDrawableJoystick> overlayJoysticks = new HashSet<>();
|
||||||
|
private InputOverlayPointer overlayPointer;
|
||||||
|
|
||||||
private boolean mIsInEditMode = false;
|
private boolean mIsInEditMode = false;
|
||||||
private InputOverlayDrawableButton mButtonBeingConfigured;
|
private InputOverlayDrawableButton mButtonBeingConfigured;
|
||||||
|
@ -128,6 +129,8 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
}
|
}
|
||||||
|
|
||||||
int pointerIndex = event.getActionIndex();
|
int pointerIndex = event.getActionIndex();
|
||||||
|
// Tracks if any button/joystick is pressed down
|
||||||
|
boolean pressed = false;
|
||||||
|
|
||||||
for (InputOverlayDrawableButton button : overlayButtons)
|
for (InputOverlayDrawableButton button : overlayButtons)
|
||||||
{
|
{
|
||||||
|
@ -142,6 +145,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
{
|
{
|
||||||
button.setPressedState(true);
|
button.setPressedState(true);
|
||||||
button.setTrackId(event.getPointerId(pointerIndex));
|
button.setTrackId(event.getPointerId(pointerIndex));
|
||||||
|
pressed = true;
|
||||||
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(),
|
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(),
|
||||||
ButtonState.PRESSED);
|
ButtonState.PRESSED);
|
||||||
}
|
}
|
||||||
|
@ -154,6 +158,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
button.setPressedState(false);
|
button.setPressedState(false);
|
||||||
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(),
|
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(),
|
||||||
ButtonState.RELEASED);
|
ButtonState.RELEASED);
|
||||||
|
button.setTrackId(-1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -166,35 +171,40 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
{
|
{
|
||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
case MotionEvent.ACTION_POINTER_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 a pointer enters the bounds of a button, press that button.
|
||||||
if (dpad.getBounds()
|
if (dpad.getBounds()
|
||||||
.contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex)))
|
.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))
|
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))
|
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))
|
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))
|
if (dpad.getBounds().right - (dpad.getWidth() / 3) < (int) event.getX(pointerIndex))
|
||||||
pressed[3] = true;
|
dpadPressed[3] = true;
|
||||||
|
|
||||||
// Release the buttons first, then press
|
// Release the buttons first, then press
|
||||||
for (int i = 0; i < pressed.length; i++)
|
for (int i = 0; i < dpadPressed.length; i++)
|
||||||
if (!pressed[i])
|
if (!dpadPressed[i])
|
||||||
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
|
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
|
||||||
ButtonState.RELEASED);
|
ButtonState.RELEASED);
|
||||||
// Press buttons
|
// Press buttons
|
||||||
for (int i = 0; i < pressed.length; i++)
|
for (int i = 0; i < dpadPressed.length; i++)
|
||||||
if (pressed[i])
|
if (dpadPressed[i])
|
||||||
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
|
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
|
||||||
ButtonState.PRESSED);
|
ButtonState.PRESSED);
|
||||||
|
|
||||||
setDpadState(dpad, pressed[0], pressed[1], pressed[2], pressed[3]);
|
setDpadState(dpad, dpadPressed[0], dpadPressed[1], dpadPressed[2], dpadPressed[3]);
|
||||||
dpad.setTrackId(event.getPointerId(pointerIndex));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP:
|
||||||
|
@ -208,6 +218,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
|
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
|
||||||
ButtonState.RELEASED);
|
ButtonState.RELEASED);
|
||||||
}
|
}
|
||||||
|
dpad.setTrackId(-1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +226,11 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
|
|
||||||
for (InputOverlayDrawableJoystick joystick : overlayJoysticks)
|
for (InputOverlayDrawableJoystick joystick : overlayJoysticks)
|
||||||
{
|
{
|
||||||
joystick.TrackEvent(event);
|
if (joystick.TrackEvent(event))
|
||||||
|
{
|
||||||
|
if (joystick.getTrackId() != -1)
|
||||||
|
pressed = true;
|
||||||
|
}
|
||||||
int[] axisIDs = joystick.getAxisIDs();
|
int[] axisIDs = joystick.getAxisIDs();
|
||||||
float[] axises = joystick.getAxisValues();
|
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();
|
invalidate();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -617,6 +644,8 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ?
|
getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ?
|
||||||
"-Portrait" : "";
|
"-Portrait" : "";
|
||||||
|
|
||||||
|
if (mPreferences.getBoolean("showInputOverlay", true))
|
||||||
|
{
|
||||||
// Add all the enabled overlay items back to the HashSet.
|
// Add all the enabled overlay items back to the HashSet.
|
||||||
if (EmulationActivity.isGameCubeGame() || mPreferences.getInt("wiiController", 3) == 0)
|
if (EmulationActivity.isGameCubeGame() || mPreferences.getInt("wiiController", 3) == 0)
|
||||||
{
|
{
|
||||||
|
@ -634,6 +663,10 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
addNunchukOverlayControls(orientation);
|
addNunchukOverlayControls(orientation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EmulationActivity.isGameCubeGame())
|
||||||
|
overlayPointer = new InputOverlayPointer(this.getContext());
|
||||||
|
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ public final class InputOverlayDrawableButton
|
||||||
public InputOverlayDrawableButton(Resources res, Bitmap defaultStateBitmap,
|
public InputOverlayDrawableButton(Resources res, Bitmap defaultStateBitmap,
|
||||||
Bitmap pressedStateBitmap, int buttonType)
|
Bitmap pressedStateBitmap, int buttonType)
|
||||||
{
|
{
|
||||||
|
mTrackId = -1;
|
||||||
mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap);
|
mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap);
|
||||||
mPressedStateBitmap = new BitmapDrawable(res, pressedStateBitmap);
|
mPressedStateBitmap = new BitmapDrawable(res, pressedStateBitmap);
|
||||||
mButtonType = buttonType;
|
mButtonType = buttonType;
|
||||||
|
|
|
@ -60,6 +60,7 @@ public final class InputOverlayDrawableDpad
|
||||||
int buttonUp, int buttonDown,
|
int buttonUp, int buttonDown,
|
||||||
int buttonLeft, int buttonRight)
|
int buttonLeft, int buttonRight)
|
||||||
{
|
{
|
||||||
|
mTrackId = -1;
|
||||||
mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap);
|
mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap);
|
||||||
mPressedOneDirectionStateBitmap = new BitmapDrawable(res, pressedOneDirectionStateBitmap);
|
mPressedOneDirectionStateBitmap = new BitmapDrawable(res, pressedOneDirectionStateBitmap);
|
||||||
mPressedTwoDirectionsStateBitmap = new BitmapDrawable(res, pressedTwoDirectionsStateBitmap);
|
mPressedTwoDirectionsStateBitmap = new BitmapDrawable(res, pressedTwoDirectionsStateBitmap);
|
||||||
|
|
|
@ -94,10 +94,11 @@ public final class InputOverlayDrawableJoystick
|
||||||
mBoundsBoxBitmap.draw(canvas);
|
mBoundsBoxBitmap.draw(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TrackEvent(MotionEvent event)
|
public boolean TrackEvent(MotionEvent event)
|
||||||
{
|
{
|
||||||
boolean reCenter = mPreferences.getBoolean("joystickRelCenter", true);
|
boolean reCenter = mPreferences.getBoolean("joystickRelCenter", true);
|
||||||
int pointerIndex = event.getActionIndex();
|
int pointerIndex = event.getActionIndex();
|
||||||
|
boolean pressed = false;
|
||||||
|
|
||||||
switch (event.getAction() & MotionEvent.ACTION_MASK)
|
switch (event.getAction() & MotionEvent.ACTION_MASK)
|
||||||
{
|
{
|
||||||
|
@ -105,7 +106,7 @@ public final class InputOverlayDrawableJoystick
|
||||||
case MotionEvent.ACTION_POINTER_DOWN:
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
if (getBounds().contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex)))
|
if (getBounds().contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex)))
|
||||||
{
|
{
|
||||||
mPressedState = true;
|
mPressedState = pressed = true;
|
||||||
mOuterBitmap.setAlpha(0);
|
mOuterBitmap.setAlpha(0);
|
||||||
mBoundsBoxBitmap.setAlpha(255);
|
mBoundsBoxBitmap.setAlpha(255);
|
||||||
if (reCenter)
|
if (reCenter)
|
||||||
|
@ -121,6 +122,7 @@ public final class InputOverlayDrawableJoystick
|
||||||
case MotionEvent.ACTION_POINTER_UP:
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
if (trackId == event.getPointerId(pointerIndex))
|
if (trackId == event.getPointerId(pointerIndex))
|
||||||
{
|
{
|
||||||
|
pressed = true;
|
||||||
mPressedState = false;
|
mPressedState = false;
|
||||||
axises[0] = axises[1] = 0.0f;
|
axises[0] = axises[1] = 0.0f;
|
||||||
mOuterBitmap.setAlpha(255);
|
mOuterBitmap.setAlpha(255);
|
||||||
|
@ -136,7 +138,7 @@ public final class InputOverlayDrawableJoystick
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trackId == -1)
|
if (trackId == -1)
|
||||||
return;
|
return pressed;
|
||||||
|
|
||||||
for (int i = 0; i < event.getPointerCount(); i++)
|
for (int i = 0; i < event.getPointerCount(); i++)
|
||||||
{
|
{
|
||||||
|
@ -158,6 +160,7 @@ public final class InputOverlayDrawableJoystick
|
||||||
SetInnerBounds();
|
SetInnerBounds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onConfigureTouch(MotionEvent event)
|
public boolean onConfigureTouch(MotionEvent event)
|
||||||
|
@ -274,4 +277,9 @@ public final class InputOverlayDrawableJoystick
|
||||||
{
|
{
|
||||||
return mHeight;
|
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 @@ private:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
|
bool IsDetectable() override { return false; }
|
||||||
Axis(int padID, ButtonManager::ButtonType index, float neg = 1.0f)
|
Axis(int padID, ButtonManager::ButtonType index, float neg = 1.0f)
|
||||||
: _padID(padID), _index(index), _neg(neg)
|
: _padID(padID), _index(index), _neg(neg)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue