summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2020-11-02 00:17:56 +0100
committerJosJuice <josjuice@gmail.com>2020-11-02 10:23:57 +0100
commita66afc864f742cf829610e14deb79e7b3ce208ca (patch)
tree8b606de311fa0a7490dc930926e1308aa2944b56 /Source/Android/app/src/main/java
parent35a113f6a2fcf1444574edc086243f79a76f7ae1 (diff)
Android/InputOverlayPointer: Don't assume surface covers whole screen
This assumption is false both in portrait mode (where it only covers the top half of the screen) and when using two apps at once. Fixes https://bugs.dolphin-emu.org/issues/12307.
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java10
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java51
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayPointer.java66
3 files changed, 59 insertions, 68 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
index 43fc64baa4..fa174c602c 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
@@ -1,6 +1,7 @@
package org.dolphinemu.dolphinemu.fragments;
import android.content.Context;
+import android.graphics.Rect;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Surface;
@@ -93,6 +94,15 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
doneButton.setOnClickListener(v -> stopConfiguringControls());
}
+ contents.post(() ->
+ {
+ int overlayX = mInputOverlay.getLeft();
+ int overlayY = mInputOverlay.getTop();
+ mInputOverlay.setSurfacePosition(new Rect(
+ surfaceView.getLeft() - overlayX, surfaceView.getTop() - overlayY,
+ surfaceView.getRight() - overlayX, surfaceView.getBottom() - overlayY));
+ });
+
// The new Surface created here will get passed to the native code via onSurfaceChanged.
return contents;
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java
index 49748166bd..fe37981ab5 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java
@@ -60,7 +60,9 @@ 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 InputOverlayPointer overlayPointer = null;
+
+ private Rect mSurfacePosition = null;
private boolean mIsFirstRun = true;
private boolean mIsInEditMode = false;
@@ -125,19 +127,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
// Load the controls if we can. If not, EmulationActivity has to do it later.
if (NativeLibrary.IsGameMetadataValid())
- {
- if (NativeLibrary.IsRunning())
- {
- // We would've needed a refreshControls call here in addition to the initTouchPointer call
- // if it wasn't for initTouchPointer calling refreshControls.
- initTouchPointer();
- }
- else
- {
- // We can't call initTouchPointer yet because it needs the aspect ratio of the running game.
- refreshControls();
- }
- }
+ refreshControls();
// Set the on touch listener.
setOnTouchListener(this);
@@ -149,24 +139,33 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
requestFocus();
}
+ public void setSurfacePosition(Rect rect)
+ {
+ mSurfacePosition = rect;
+ initTouchPointer();
+ }
+
public void initTouchPointer()
{
- // Refresh before starting the pointer
- refreshControls();
+ // Check if we have all the data we need yet
+ boolean aspectRatioAvailable = NativeLibrary.IsRunning() && !NativeLibrary.IsBooting();
+ if (!aspectRatioAvailable || mSurfacePosition == null)
+ return;
- if (NativeLibrary.IsEmulatingWii())
- {
- int doubleTapButton = IntSetting.MAIN_DOUBLE_TAP_BUTTON.getIntGlobal();
+ // Check if there's any point in running the pointer code
+ if (!NativeLibrary.IsEmulatingWii())
+ return;
- if (mPreferences.getInt("wiiController", OVERLAY_WIIMOTE_NUNCHUK) !=
- InputOverlay.OVERLAY_WIIMOTE_CLASSIC &&
- doubleTapButton == InputOverlayPointer.DOUBLE_TAP_CLASSIC_A)
- {
- doubleTapButton = InputOverlayPointer.DOUBLE_TAP_A;
- }
+ int doubleTapButton = IntSetting.MAIN_DOUBLE_TAP_BUTTON.getIntGlobal();
- overlayPointer = new InputOverlayPointer(this.getContext(), doubleTapButton);
+ if (mPreferences.getInt("wiiController", OVERLAY_WIIMOTE_NUNCHUK) !=
+ InputOverlay.OVERLAY_WIIMOTE_CLASSIC &&
+ doubleTapButton == InputOverlayPointer.DOUBLE_TAP_CLASSIC_A)
+ {
+ doubleTapButton = InputOverlayPointer.DOUBLE_TAP_A;
}
+
+ overlayPointer = new InputOverlayPointer(mSurfacePosition, doubleTapButton);
}
@Override
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayPointer.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayPointer.java
index c56853cf88..cd3653d318 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayPointer.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayPointer.java
@@ -1,10 +1,7 @@
package org.dolphinemu.dolphinemu.overlay;
-import android.app.Activity;
-import android.content.Context;
+import android.graphics.Rect;
import android.os.Handler;
-import android.util.DisplayMetrics;
-import android.view.Display;
import android.view.MotionEvent;
import org.dolphinemu.dolphinemu.NativeLibrary;
@@ -20,10 +17,11 @@ public class InputOverlayPointer
private final float[] axes = {0f, 0f};
- private float maxHeight;
- private float maxWidth;
- private float aspectAdjusted;
- private boolean xAdjusted;
+ private float mGameCenterX;
+ private float mGameCenterY;
+ private float mGameWidthHalfInv;
+ private float mGameHeightHalfInv;
+
private boolean doubleTap = false;
private int doubleTapButton;
private int trackId = -1;
@@ -38,39 +36,33 @@ public class InputOverlayPointer
DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.CLASSIC_BUTTON_A);
}
- public InputOverlayPointer(Context context, int button)
+ public InputOverlayPointer(Rect surfacePosition, int button)
{
- Display display = ((Activity) context).getWindowManager().getDefaultDisplay();
- DisplayMetrics outMetrics = new DisplayMetrics();
- display.getMetrics(outMetrics);
doubleTapButton = button;
- Integer y = outMetrics.heightPixels;
- Integer x = outMetrics.widthPixels;
+ 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 deviceAR = (float) x / y;
+ float surfaceAR = gameWidth / gameHeight;
float gameAR = NativeLibrary.GetGameAspectRatio();
- aspectAdjusted = gameAR / deviceAR;
- if (gameAR <= deviceAR) // Black bars on left/right
+ if (gameAR <= surfaceAR)
{
- xAdjusted = true;
- Integer gameX = Math.round((float) y * gameAR);
- Integer buffer = (x - gameX);
-
- maxWidth = (float) (x - buffer) / 2;
- maxHeight = (float) y / 2;
+ // Black bars on left/right
+ gameWidth = gameHeight * gameAR;
}
- else // Bars on top/bottom
+ else
{
- xAdjusted = false;
- Integer gameY = Math.round((float) x / gameAR);
- Integer buffer = (y - gameY);
-
- maxWidth = (float) x / 2;
- maxHeight = (float) (y - buffer) / 2;
+ // 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)
@@ -94,18 +86,8 @@ public class InputOverlayPointer
if (trackId == -1)
return;
- int x = (int) event.getX(event.findPointerIndex(trackId));
- int y = (int) event.getY(event.findPointerIndex(trackId));
- if (xAdjusted)
- {
- axes[0] = (y - maxHeight) / maxHeight;
- axes[1] = ((x * aspectAdjusted) - maxWidth) / maxWidth;
- }
- else
- {
- axes[0] = ((y * aspectAdjusted) - maxHeight) / maxHeight;
- axes[1] = (x - maxWidth) / maxWidth;
- }
+ axes[0] = (event.getY(event.findPointerIndex(trackId)) - mGameCenterY) * mGameHeightHalfInv;
+ axes[1] = (event.getX(event.findPointerIndex(trackId)) - mGameCenterX) * mGameWidthHalfInv;
}
private void touchPress()