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 d8f8c02743..4cdb0051e5 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 overlayButtons = new HashSet<>(); private final Set overlayDpads = new HashSet<>(); private final Set 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()) + // Check if there's any point in running the pointer code + if (!NativeLibrary.IsEmulatingWii()) + return; + + int doubleTapButton = IntSetting.MAIN_DOUBLE_TAP_BUTTON.getIntGlobal(); + + if (mPreferences.getInt("wiiController", OVERLAY_WIIMOTE_NUNCHUK) != + InputOverlay.OVERLAY_WIIMOTE_CLASSIC && + doubleTapButton == InputOverlayPointer.DOUBLE_TAP_CLASSIC_A) { - int doubleTapButton = IntSetting.MAIN_DOUBLE_TAP_BUTTON.getIntGlobal(); - - 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(this.getContext(), doubleTapButton); + 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()