Merge pull request #9215 from JosJuice/android-pointer-portrait

Android/InputOverlayPointer: Don't assume surface covers whole screen
This commit is contained in:
LC 2020-11-02 18:05:47 -05:00 committed by GitHub
commit d5c0a9a185
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 69 deletions

View File

@ -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;

View File

@ -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())
// 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

View File

@ -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()